diff options
Diffstat (limited to 'archive')
231 files changed, 88043 insertions, 0 deletions
diff --git a/archive/Readme b/archive/Readme new file mode 100644 index 0000000..8eb62d0 --- /dev/null +++ b/archive/Readme @@ -0,0 +1,3 @@ +Archive of the dead old releases... + +They might be re-released in the form of level packs someday...
\ No newline at end of file diff --git a/archive/blr1/ChangeLog b/archive/blr1/ChangeLog new file mode 100644 index 0000000..6125f79 --- /dev/null +++ b/archive/blr1/ChangeLog @@ -0,0 +1,40 @@ +0.5.3
+-Fixed a problem in bullet position calculating.
+0.5.4
+-Replaces arc- functions to make calculating more efficient.
+0.7.0
+-Levels->7
+0.7.4
+-Clear range added
+0.8.4
+-Limiting clear range usage. Freezing Level design.
+0.8.6
+-Adding readme files. Fixing small bugs in program.
+-Semi-Collision Effects.
+0.8.7α
+-Spliting main.cpp into mulitiple headers.
+-Compressing resources.
+-Removing dependency of Bass.dll
+0.8.8α
+-Maintaince version.
+0.8.9α
+-Rewriting menus, pause etc. added.
+-Highscore recording. Basic level complete information.
+-Average FPS.
+-Preparation for porting to Linux.
+1.0.0 Pre-Release
+-Upgrading hge graphic engine to DirectX9.
+-Removing some cheats.
+-Linux version built successfully(using hge-unix).
+1.0.1 Pre-Release
+-Embedding HGE into project, getting rid of hge.dll
+-Merging configuration program.
+-Adding first start up configuration, no initial configuration file needed.
+1.0.2 Pre-Release
+-Sync code with Bullet Lab Remix II.
+-Status->Main Functions Frozen+Core Frozen+Level Frozen.
+-Fix some bugs with the keyboard and the render engine.
+-Trying SFX and Music.
+1.0.3 Stable Release
+-Fix hidden bullets.
+-Build up for final release.
\ No newline at end of file diff --git a/archive/blr1/Compiling.txt b/archive/blr1/Compiling.txt new file mode 100644 index 0000000..b883265 --- /dev/null +++ b/archive/blr1/Compiling.txt @@ -0,0 +1,9 @@ +Compiling BLR under Linux +1. Get HGE UNIX here: http://icculus.org/hge-unix/. +2. Replace the same files in hge-unix using the files in /hgehack. +3. Compile and install hge-unix. +4. Run compile if hge-unix has been successfully installed. +5. Enjoy BLR by executing BulletLabRemix! +If you have any problem compiling BLR, just write a feedback. +Email: chirs241097@163.com +Forum: http://tieba.baidu.com/f?kw=chrisoft
\ No newline at end of file diff --git a/archive/blr1/Compiling_zh.txt b/archive/blr1/Compiling_zh.txt new file mode 100644 index 0000000..8f3acf8 --- /dev/null +++ b/archive/blr1/Compiling_zh.txt @@ -0,0 +1,9 @@ +在Linux下编译BLR +1. 获å–HGE-UNIX: http://icculus.org/hge-unix/。 +2. 用/hgehack内的文件替æ¢hge-unix里的åŒå文件。 +3. 编译并安装hge-unix。 +4. 如果hge-unixå·²ç»æˆåŠŸå®‰è£…,è¿è¡Œcompile脚本。 +5. è¿è¡ŒBulletLabRemixï¼ +å¦‚æžœä½ åœ¨ç¼–è¯‘æ—¶é‡åˆ°äº†ä»»ä½•é—®é¢˜ï¼Œè¯·ä¸Žä½œè€…è”系。 +Email: chirs241097@163.com +è´´å§: http://tieba.baidu.com/f?kw=chrisoft diff --git a/archive/blr1/README.txt b/archive/blr1/README.txt new file mode 100644 index 0000000..e5b1ddc --- /dev/null +++ b/archive/blr1/README.txt @@ -0,0 +1,178 @@ +/*************************************\
+ * Bullet Lab Remix HGE 1.0.3 *
+ * The Creature of Colour *
+ * CopyLeft Chris Xiong *
+ * Readme File for binary release *
+\*************************************/
+*************************************************************
+First, I'm glad to annonce the first stable release of BLR.
+After three and a half of lazy work, BLR1 Stable came out at last.
+Well, this is just the start. Let's expect BLR2!
+*************************************************************
+WARNING: Everything works correctly on my computer, but I can't guarantee the same
+thing will happen on your computer!
+----------------------------------------------------------------------------------
+Why I am writting this "Game":
+
+-Do not care details...
+----------------------------------------------------------------------------------
+Attention: If you are using Linux, just ignore this and read Compiling.txt
+Basic requirements of this game:
+
+Hardware requirements:
+CPU: Better than none.
+RAM: If you are using Windows XP+, you can ignore this.
+GPU: Any GPU supporting DirectX 9 is okay.
+A keyboard is necessary. Although this game doesn't use a mouse to control, you'd
+better have one to use your operating system...
+
+Software requirements:
+If your computer is not from the last century and the game wouldn't start, check...
+If DirectX 9 Runtime is installed.
+If you are using Windows XP or later version.
+
+Something else...:
+CheatEngine (Optional, recommended for people who are urgent to highscores.)
+No Trypophobia! (Important!!)
+
+Additional:
+To run it in High FPS mode (much better experience than Low FPS mode)
+-Turn on "Lock FPS to the highest level" in BLR config
+-Configure your GPU correctly. A mis-configured GPU can cause many problems...
+-Have a stronger CPU. Quad core is recommended.
+
+If FPS is only around 500... Just give it up... Turn on Low FPS mode in BLR config.
+
+Another small tip:
+I found that Intel HD Graphics always get the highest FPS easily...
+----------------------------------------------------------------------------------
+[Attention!]: The topic below is for those who have tried to play but failed.
+
+Operating with keyboard:
+Arrow keys: Move
+Shift+Arrow keys: Precise move (If you ignore this you will probably NEVER pass easy)
+(Well, I was joking. You can "Continue" anyway.)
+Z (or X, determined in your configuration): Call Clear Range
+Z/Enter(In menus): Confirm
+Esc(In game): Pause
+
+Collision & "Semi-collision":
+Only a VERY close distance will be treat as a collision (about 2 pixels, imagine that.)
+Other bullets passed by you(in 4 pixels) will be treat as a semi-collision, which would
+plus your score by 2000.
+
+Configuring the player:
+You can customize the player in the Player Profile menu.
+You can determine the player's moving speed(both in normal mode or precise mode).
+And a clear range bonus.
+You should know that you are customizing yourself in the limit of "Ability Points".
+----------------------------------------------------------------------------------
+Softwared used to develop Bullet Lab Remix:
+Visual Studio 2012 (Compiler)
+DirectX SDK (Aug. 2009)
+HGE (Packed DirectX APIs)
+Photosohop CS6 for graphic resources
+Inkscape for vector graphics
+Porting to Linux is also done by Chris Xiong, using Kwrite and Geany.
+----------------------------------------------------------------------------------
+Frequently Asked Questions and my own problems
+
+Q: ...The game crashes and quit automatically?
+A: I didn't have that problem... This may be caused by a wrong RAM access.
+ Make sure you have enough RAM to run this game.
+
+Q: It stopped working just before the menu appears...
+A: Well, I use "freopen" for file operations. M$ said that's not safe but I insisted..
+ Just be patient and restart the game.
+
+Q: Huge RAM usage?
+A: The main code uses less than 5 MB RAM. However, levels with too much bullets may
+ use a huge amount of RAM.
+
+Q: "Cannot decompress resources!"
+A: Resources used in this game have been compressed with Microsoft LZ compresss program.
+ If you meet this fault, check if there's already a folder called "Decompressed" in
+ the Resources folder. If so, delete it. (Now the program could delete it automatically
+ even the error has already been reported. So you may not find this folder. Just restart
+ the game)
+ If that doesn't work, check if "expand.exe" is included in your system.
+
+Q: Everything runs slowly!
+A: Check FPS which is displayed at the right bottom corner of the game. The game
+ should run at at least 850 FPS (In HighFPS mode).
+ If it is below 700 (at the menu scene), turn on Low FPS mode using the
+ configure application.
+ If it is fixed at 60 and it is running EXTREMELY slowly, try turn off vertical
+ sync first (in your graphics driver settings). If it doesn't work, turn on Low
+ FPS mode.
+ Please note that Low FPS mode may provide a horrible experience...
+
+Q: What is "Average FPS"?
+A: Average FPS is the average of FPS during the game(WTF!). It showed how your computer felt during
+ the game...
+
+Q: Tell me something about the UI.
+A: The main menu:
+ Start---------------Enter the difficulty selecting menu.
+ Highscore && Records--------Enter highscore view selecting menu.
+ Options--------------Enter options menu.
+ Credits--------------Show a long, dull credits list.
+ Exit---------------Parents are coming!!!
+ The difficulty selecting menu:
+ Easy---------------Difficulty without difficulty.
+ Normal--------------For most human-beings.
+ Extreme--------------Who would like to try?
+ Free Play Mode----------No deaths, go for highest score.
+ Back---------------Giving up?
+ The Options menu:
+ Fullscreen: ...----------Toggle fullscreen, the settings will be applied after restarting the game.
+ FPS Level: ...-------------Toggle FPS level mode. Possible modes are: Low FPS, Highest and Natural.
+Use Key . for Clear Range------Change the key to call Clear Range.
+ Player Profile-------------Customize the player.
+ Back------------------Done setting, I'm ready!
+Tips:
+ If supported, you can toggle fullscreen in game by pressing Alt+Enter. However this won't affect your settings.
+ Use key Left/Right to adjust values in Player Profile page.
+
+Q: How to load default configuration?
+A: To load default configuration, just delete blr.cfg. Then start BLR, you can do your initial settings again.
+ Attention: YOUR SCORE FILE WILL BE CLEARED AS WELL!!
+
+Q: When I use a Clear Range, FPS falls terriblely.
+A: This is normal... Because the code of Clear Range is terribly inefficient...
+
+Q: Some levels are impossible to pass!
+A: That may be true... (I got the same result from some of the testers)
+ However this is an excuse, I think.
+
+Q: Ain't there any background?
+A: It is painful to think about a background...
+ So think about your own background... everyone will have his own version...(Chemistry Laboratory etc.)
+
+Q: Where to get the source code?
+A: The source code is terribly ugly...
+ However, when I release the binary version, I will also release a tarball of
+ the source code.
+ To be more creative, WRITE YOUR OWN CODE.
+----------------------------------------------------------------------------------
+Version History && Planning Versions
+For detailed information, view CHANGELOG.txt.
+
+1.0.3sr: Hope this fix for hidden bullets could work!
+1.0.2pr: Some input event fixes. Fixed a problem in the render engine. Get rid of the config program.
+1.0.1pr: Get rid of hge.dll. Merging hge into project.
+1.0.0pr: Fixing small bugs and cheats. Upgrading DirectX to DX9. Trying porting to Linux.
+0.8.9α : Adding a lot of lacking functions in earlier versions.
+0.8.8α : Small fixes for adding functions.
+0.8.7α : Preparation for 1.0.0, categorizing code, bug fixes, resoureces compression andadding some effects etc.
+0.8.6α : Second released version, small bugs fixed, a better icon for configure program.
+0.8.4α : First released version, most cheats are removed, level frozen version(No new levels will be added).
+0.7.4 : A developer only version, the game system is almost completed.
+0.7.0 : A developer only version, 7 levels available now.
+0.5.3 : A developer only version, 5 levels available now, added collision and semi-collision detection.
+0.2.1 : First tower, first bullet. 2 basic levels completed. Basic effects added.
+0.0.1 : Only a main menu!
+
+2013-5-11: Project Started
+Let's remember the great day!
+Thank everyone that waste time to test my poor project!
\ No newline at end of file diff --git a/archive/blr1/README_zh.txt b/archive/blr1/README_zh.txt new file mode 100644 index 0000000..d4f8f25 --- /dev/null +++ b/archive/blr1/README_zh.txt @@ -0,0 +1,166 @@ +/*************************************\
+ * Bullet Lab Remix HGE 1.0.3 * ->åŽæ–‡å°†ç§°å…¶ä¸ºBLR
+ * The Creature of Colour *
+ * 版æƒæ‰€æ— Chris Xiong *
+ * å¯æ‰§è¡Œæ–‡ä»¶è‡ªè¿° *
+\*************************************/
+*************************************************************
+首先,éžå¸¸é«˜å…´åœ°â€œå®£å¸ƒâ€BLR1çš„æ£å¼ç‰ˆç»ˆäºŽå¯ä»¥å‘布了ï¼
+ç»è¿‡ä¸‰ä¸ªåŠæœˆçš„å·æ‡’工作,BLR1çš„æ£å¼ç‰ˆç»ˆäºŽå‡ºæ¥äº†ã€‚。
+当然,这åªæ˜¯ä¸ªå¼€å§‹ã€‚ç‰å¾…BLR2çš„å¼€å‘å§ï¼
+*************************************************************
+è¦å‘Šï¼šä¸ä¿è¯æœ¬ç¨‹åºåœ¨æ‰€æœ‰è®¡ç®—机上都能æ£å¸¸è¿è¡Œã€‚
+----------------------------------------------------------------------------------
+ä¸ºä»€ä¹ˆå†™è¿™ç ´çŽ©æ„?
+
+-ä¸è¦åœ¨æ„细节。。。
+----------------------------------------------------------------------------------
+注æ„ï¼šå¦‚æžœä½ æ£åœ¨ä½¿ç”¨Linuxï¼Œæ— è§†è¿™éƒ¨åˆ†å†…å®¹å¥½äº†ã€‚ç›´æŽ¥åŽ»çœ‹Compiling_CHS.txt。
+è¿è¡ŒBLR的基本è¦æ±‚:
+
+硬件需求
+CPU: è¦æ¯”没有强。
+RAM: å¦‚æžœä½ çš„æ“作系统能够å¯åŠ¨ï¼Œè¿™é¡¹å¯ä»¥å¿½ç•¥ã€‚
+GPU: 任何支æŒDirectX9çš„GPU都行。
+键盘是必è¦çš„。虽然本游æˆä¸éœ€è¦é¼ æ ‡æ¥æ“ä½œï¼Œä½ ä¹Ÿæœ€å¥½ç”¨é¼ æ ‡æ¥ä½¿ç”¨æ¥æŽ§åˆ¶æ“作系统。。。
+
+软件需求
+å¦‚æžœä½ çš„ç”µè„‘ä¸æ˜¯ä»Žä¸Šä¸–纪æ¥çš„,但是游æˆä»æ— 法å¯åŠ¨ï¼Œæ£€æŸ¥ï¼š
+DirectX9è¿è¡Œåº“是å¦å·²ç»å®‰è£…
+ä½ è¿è¡Œçš„是å¦æ˜¯Windows XP或以åŽçš„版本。
+
+其他
+CheatEngine (éžå¿…需。这是为那些特别想è¦é«˜åˆ†çš„人准备的)
+没有密集æ惧症(éžå¸¸é‡è¦ï¼)
+
+é™„åŠ æ¡ä»¶ï¼š
+è¦æƒ³åœ¨é«˜å¸§çŽ‡æ¨¡å¼ä¸‹è¿è¡Œï¼ˆ1000FPS,æµç•…åº¦è‡ªè¡Œæƒ³è±¡ï¼‰ï¼Œä½ éœ€è¦ï¼š
+-在设置程åºä¸æ‰“å¼€"Lock FPS to the highest level"(将帧率é”定在最大值)
+-æ£ç¡®åœ°è®¾ç½®ä½ çš„GPU。错误的设置å¯èƒ½å¯¼è‡´è®¸å¤šé—®é¢˜ã€‚。
+-è¦æœ‰ä¸€é¢—足够快的CPUï¼Œæœ€å¥½å››æ ¸
+
+如果FPSåªåœ¨500附近(或者更低),放弃å§ã€‚。。在设置程åºå†…打开
+"Low FPS mode"(低帧率模å¼ï¼Œ60FPS)
+
+æ— æ„义内容:
+我å‘现Intel集æˆæ˜¾å¡æ€»æ˜¯éžå¸¸å®¹æ˜“地达到1000FPS。。。
+----------------------------------------------------------------------------------
+注æ„:以下内容是为å°è¯•è¿‡ä½†æ˜¯å¤±è´¥äº†çš„人写的。
+
+如何用键盘æ“作:
+æ–¹å‘键:移动
+Shift+æ–¹å‘é”®ï¼šç²¾ç¡®ç§»åŠ¨ï¼ˆå¦‚æžœä½ æ— è§†è¿™ä¸ªä½ å¯èƒ½æ°¸è¿œæ— 法通过Easy关)
+(当然,我åªæ˜¯å¼€çŽ©ç¬‘ã€‚æ— è®ºå¦‚ä½•ä½ ä¹Ÿå¯ä»¥é€‰æ‹©ç»§ç»ã€‚。。)
+Z(或者是X,å–å†³äºŽä½ çš„è®¾ç½®ï¼‰ï¼šè°ƒç”¨Clear Range。
+(在èœå•ä¸ï¼‰Z或回车:确认
+Esc(在游æˆç•Œé¢ï¼‰ï¼šæš‚åœ
+
+碰撞和所谓的åŠç¢°æ’žï¼ˆ<-è‡ªé€ è¯ï¼‰
+åªæœ‰ã€ç‰¹åˆ«è¿‘】的接触将会被当作是碰撞(大于仅有两个åƒç´ ,想象一下)
+å…¶ä»–ä»Žä½ é™„è¿‘é£žè¿‡çš„å弹(约4åƒç´ )将会被当作“åŠç¢°æ’žâ€ï¼Œæ¯æ¬¡å°†åŠ 分2000点。
+
+è®¾ç½®ä½ æ‰€æŽ§åˆ¶çš„å°æ–¹å—:
+ä½ å¯ä»¥åœ¨çŽ©å®¶è®¾å®šèœå•è‡ªè¡Œå†³å®šå°æ–¹å—的属性。
+ä½ å¯ä»¥è®¾ç½®çš„项目有移动速度(普通移动和精确移动速度都å¯ä»¥è®¾å®šï¼‰å’Œé¢å¤–çš„Clear Range。
+当然,ä¸èƒ½éšä¾¿è®¾ç½®ã€‚需è¦åœ¨"Ability Points"(能力点)的é™åˆ¶ä¹‹å†…。
+----------------------------------------------------------------------------------
+å¼€å‘所用的软件
+Visual Studio 2012(编译器)
+DirectX SDK (Aug. 2009)
+HGE(å°è£…DirectX接å£ï¼‰
+Photoshop CS6处ç†å›¾å½¢èµ„æº
+Inkscape处ç†çŸ¢é‡å›¾
+移æ¤åˆ°Linux的工作也是由作者自行完æˆçš„。使用了kwriteå’ŒGeany。
+----------------------------------------------------------------------------------
+常è§é—®é¢˜å’Œæˆ‘自己的问题
+
+Q: 游æˆå´©æºƒäº†å¹¶è‡ªåŠ¨é€€å‡ºã€‚。
+A: 我没é‡åˆ°è¿‡æ¤ç±»é—®é¢˜ã€‚。å¯èƒ½æ˜¯ç”±äºŽé”™è¯¯çš„RAMå˜å–。
+ ä¿è¯ä½ 有足够的内å˜ã€‚
+
+Q: 它在èœå•å‡ºçŽ°å‰å°±åœæ¢å·¥ä½œã€‚。。
+A: 我用了freopenæ¥å¤„ç†æ–‡ä»¶ã€‚微软说那å¯èƒ½ä¸å®‰å…¨ä½†æˆ‘没有ç†ä»–。é‡å¯æ¸¸æˆå°±å¥½äº†ã€‚
+
+Q: 巨大的RAM开销。。
+A: 主程åºä»…å 用5MB内å˜ã€‚但是,å弹太多的关å¡å¯èƒ½ç”¨å¾ˆå¤šçš„RAM。
+
+Q: "Cannot decompress resources!"ï¼ˆæ— æ³•è§£åŽ‹èµ„æºï¼ï¼‰
+A: 本游æˆä½¿ç”¨çš„资æºå·²ç»ä½¿ç”¨å¾®è½¯çš„压缩程åºåŽ‹ç¼©è¿‡äº†ã€‚å¦‚æžœä½ é‡åˆ°äº†è¿™ä¸ªé—®é¢˜ï¼Œæ£€æŸ¥æ¸¸æˆèµ„æºæ–‡ä»¶å¤¹
+ (/Resources/)内是å¦å·²ç»æœ‰äº†ä¸€ä¸ªå«åš"Decompressed"çš„æ–‡ä»¶å¤¹ã€‚å¦‚æžœæœ‰ï¼Œåˆ æŽ‰å®ƒã€‚ï¼ˆå³ä½¿å·²ç»æŠ¥é”™ï¼Œ
+ 程åºçŽ°åœ¨å·²ç»å¯ä»¥è‡ªåŠ¨åˆ æŽ‰å®ƒäº†ï¼Œæ‰€ä»¥ä½ å¯èƒ½æ‰¾ä¸åˆ°è¿™ä¸ªæ–‡ä»¶å¤¹ï¼Œé‡å¯æ¸¸æˆå³å¯ï¼‰
+ 如果那ä¸ç®¡ç”¨ï¼Œæ£€æŸ¥/system32里是å¦æœ‰expand.exe。
+
+Q: 一切都è¿è¡Œç¼“æ…¢ï¼
+A: 看看显示在å³ä¸‹è§’çš„FPS数。æ¤æ¸¸æˆåº”该至少è¿è¡Œåœ¨850FPS(在高帧率模å¼ä¸‹ï¼‰ã€‚
+ 如果主èœå•çš„FPS也å°äºŽ700,用设置程åºæ‰“开低帧率模å¼ã€‚
+ 如果帧率固定在60FPS并且è¿è¡Œã€æžå…¶ã€‘缓慢,先试试关掉显å¡çš„åž‚ç›´åŒæ¥ã€‚ä¸è¡Œå†ç”¨ä½Žå¸§çŽ‡æ¨¡å¼ã€‚
+ 请注æ„低帧率模å¼å¯èƒ½å¸¦æ¥æŽ¥è¿‘æ怖的体验。。。
+
+Q: 什么是"Average FPS"(平å‡å¸§çŽ‡ï¼‰ï¼Ÿ
+A: Average FPS就是平å‡å¸§çŽ‡ï¼ˆä»€ä¹ˆçŽ©æ„å„¿ã€‚ã€‚ï¼‰ã€‚å®ƒè¡¨ç¤ºäº†ä½ çš„ç”µè„‘çš„åœ¨æ¸¸æˆä¸çš„å—罪程度。。。
+ (CPU压力什么的)
+
+Q: ç•Œé¢ä¸Šéƒ½æ˜¯ä»€ä¹ˆæ„æ€ã€‚。
+A: 主èœå•ï¼š
+ Start---------------开始。进入难度选择界é¢
+ Highscore && Records--------高分和记录。在这里回顾高分(记录是数æ®ï¼Œä¸æ˜¯å½•åƒï¼ï¼‰
+ Options--------------选项èœå•
+ Credits--------------åˆ¶ä½œè€…ã€‚æ˜¾ç¤ºä¸€ä¸ªé•¿è€Œæ— èŠçš„制作者åå•ï¼ˆå°±ä¸€ä¸ªâ€œåˆ¶ä½œè€…â€ï¼Œå¯¹å§ã€‚。)
+ Exit---------------退出。家长æ¥äº†ï¼ï¼ï¼
+ 难度选择èœå•ï¼š
+ Easy---------------没有难度的难度。
+ Normal--------------为大部分人准备的难度。
+ Extreme--------------è°æ„¿æ„试试?
+ Free Play Mode----------ä¸æ»æ¨¡å¼ï¼Œåˆ·åˆ†ä¸“用。
+ Back---------------放弃了?
+ 选项èœå•ï¼š
+ Fullscreen: ...----------切æ¢å…¨å±æ˜¾ç¤ºã€‚é‡å¯æ¸¸æˆåŽç”Ÿæ•ˆã€‚
+ FPS Level: ...-------------切æ¢FPS模å¼ã€‚å¯èƒ½çš„选项为:Low FPS(低帧率),Highest(最高)和Natural(ä¸é™åˆ¶ï¼‰ã€‚
+Use key . for Clear Range------选择用X或者是Z键使用Clear Range
+ Player Profile-------------自定义玩家属性。
+ Back------------------完æˆè®¾ç½®ã€‚
+Tips:
+ 如果电脑支æŒï¼Œä½ å¯ä»¥åœ¨æ¸¸æˆä¸ç”¨Alt+回车æ¥åˆ‡æ¢å…¨å±ã€‚但这ä¸ä¼šæ”¹å†™é…置文件。
+ 在玩家设定页é¢å†…用左å³é”®æ¥è°ƒæ•´æ•°å€¼ã€‚
+
+Q: 如何æ¢å¤åŽŸå§‹è®¾å®šï¼Ÿ
+A: åªéœ€è¦åˆ 除blr.cfg这个文件。然åŽå¯åŠ¨BLR,就å¯ä»¥é‡æ–°åšåˆå§‹åŒ–设定了。
+ 注æ„ï¼šä½ çš„åˆ†æ•°æ–‡ä»¶ä¹Ÿå°†è¢«æ¸…ç©ºï¼
+
+Q: 用了Clear Range之åŽFPS严é‡ä¸‹é™ã€‚
+A: 这很æ£å¸¸ã€‚。Clear Range的代ç 效率ä¸é«˜ã€‚
+
+Q: 有些关过ä¸äº†ï¼
+A: å¯èƒ½æ˜¯çœŸçš„å§ï¼ˆæˆ‘从一些测试人员那里也得到了相åŒçš„结果)
+ 但是这å¯èƒ½æ˜¯ä¸ªå€Ÿå£ï¼Œæˆ‘想。(è¯åºé”™ä¹±ï¼‰
+
+Q: 没有背景(所谓的background)?
+A: 想一个背景是痛苦的事情。。
+ 自己YY一个å§ã€‚。æ¯ä¸ªäººéƒ½ä¼šæœ‰ä»–自己的版本。。(化å¦å®žéªŒå®¤ä¹‹ç±»çš„)
+
+Q: 如何å–å¾—æºä»£ç ?
+A: 代ç 写的éžå¸¸ä¸‘陋。。
+ 但是æ¯æ¬¡å‘布å¯æ‰§è¡Œæ–‡ä»¶æ—¶ï¼Œæˆ‘也会å‘布一个æºä»£ç 包。
+ 为了创新,ã€è¿˜æ˜¯å†™è‡ªå·±çš„代ç 】。
+----------------------------------------------------------------------------------
+版本历å²å’Œä»¥åŽçš„版本
+有关版本的详细信æ¯ï¼Œè¯·è§ChangeLog
+
+1.0.3sr: 希望这次解决éšè—å弹的方案没有问题。。
+1.0.2pr: 解决了一些键盘和渲染引擎的问题。将é…置程åºå¹¶å…¥æ¸¸æˆä¸ã€‚
+1.0.1pr: ä¸å†ä¾èµ–hge.dll。将hge并入工程。
+1.0.0pr: 解决å°çš„问题,å°ä¸€éƒ¨åˆ†cheats。å‡çº§DirectX到DX9。移æ¤Linux版工作开始。
+0.8.9α : æ·»åŠ äº†ä¸€å †æ—©æœŸç‰ˆæœ¬ç¼ºå¤±çš„åŠŸèƒ½ã€‚
+0.8.8α : ä¸ºæ·»åŠ åŠŸèƒ½åšå‡†å¤‡ã€‚
+0.8.7α : 为1.0.0åšå‡†å¤‡ã€‚代ç 分类,解决å°é—®é¢˜ï¼ŒåŽ‹ç¼©èµ„æºå¹¶æ·»åŠ 一些特效。
+0.8.6α : 第二个å‘布版本,解决了一部分问题。æ¢äº†å›¾æ ‡ã€‚
+0.8.4α : 第一个å‘布版本。移除了一部分内挂(。。。)。关å¡å†»ç»“版本(ä¸ä¼šå†æ·»åŠ æ–°çš„å…³å¡ï¼‰
+0.7.4 : å¼€å‘者版本。游æˆç³»ç»Ÿå·²ç»åŸºæœ¬å®Œæˆã€‚
+0.7.0 : å¼€å‘者版本。有7个关å¡ã€‚
+0.5.3 : å¼€å‘者版本。已有5å…³ã€‚æ·»åŠ äº†ç¢°æ’žæ£€æµ‹ã€‚
+0.2.1 : 一切的开始。写完了两关。最基本的效果。
+0.0.1 : èœå•ã€‚。
+
+2013-5-11: 工程开始。
+让我们记ä½è¿™ä¼Ÿå¤§çš„一天ï¼
+感谢所有浪费时间æ¥æµ‹è¯•è¿™ä¸ªçƒ‚工程的人ï¼
\ No newline at end of file diff --git a/archive/blr1/VERSION.txt b/archive/blr1/VERSION.txt new file mode 100644 index 0000000..245832a --- /dev/null +++ b/archive/blr1/VERSION.txt @@ -0,0 +1 @@ +1.0.3 Stable release
\ No newline at end of file diff --git a/archive/blr1/resources/bg.png b/archive/blr1/resources/bg.png Binary files differnew file mode 100644 index 0000000..bb0a8a2 --- /dev/null +++ b/archive/blr1/resources/bg.png diff --git a/archive/blr1/resources/blnsns.png b/archive/blr1/resources/blnsns.png Binary files differnew file mode 100644 index 0000000..8651ee1 --- /dev/null +++ b/archive/blr1/resources/blnsns.png diff --git a/archive/blr1/resources/charmap.fnt b/archive/blr1/resources/charmap.fnt new file mode 100644 index 0000000..4d90feb --- /dev/null +++ b/archive/blr1/resources/charmap.fnt @@ -0,0 +1,99 @@ +[HGEFONT]
+
+Bitmap=blnsns.png
+
+Char=" ",1,1,3,30,-1,5
+Char="!",5,1,5,30,1,0
+Char=""",11,1,8,30,0,0
+Char="#",20,1,18,30,0,0
+Char="$",39,1,12,30,0,0
+Char="%",52,1,20,30,0,0
+Char="&",73,1,19,30,0,0
+Char="'",93,1,4,30,0,1
+Char="(",98,1,10,30,0,-1
+Char=")",109,1,10,30,-1,0
+Char="*",120,1,11,30,0,-1
+Char="+",132,1,12,30,-1,0
+Char=",",145,1,7,30,-1,0
+Char="-",153,1,10,30,0,0
+Char=".",164,1,6,30,0,0
+Char="/",171,1,10,30,-1,-1
+Char="0",182,1,16,30,0,0
+Char="1",199,1,7,30,0,1
+Char="2",207,1,15,30,-1,-1
+Char="3",223,1,14,30,-1,0
+Char="4",238,1,14,30,0,0
+Char="5",1,32,14,30,-1,0
+Char="6",16,32,14,30,0,0
+Char="7",31,32,14,30,-1,-1
+Char="8",46,32,13,30,-1,0
+Char="9",60,32,14,30,0,0
+Char=":",75,32,6,30,0,0
+Char=";",82,32,7,30,-1,0
+Char="<",90,32,10,30,0,0
+Char="=",101,32,12,30,0,0
+Char=">",114,32,10,30,0,0
+Char="?",125,32,12,30,-1,0
+Char="@",138,32,17,30,0,0
+Char="A",156,32,19,30,-1,0
+Char="B",176,32,16,30,1,0
+Char="C",193,32,17,30,0,-1
+Char="D",211,32,17,30,1,0
+Char="E",229,32,14,30,1,0
+Char="F",1,63,13,30,1,0
+Char="G",15,63,18,30,0,0
+Char="H",34,63,17,30,1,1
+Char="I",52,63,5,30,1,1
+Char="J",58,63,7,30,0,1
+Char="K",66,63,16,30,1,-1
+Char="L",83,63,13,30,1,0
+Char="M",97,63,19,30,1,1
+Char="N",117,63,17,30,1,1
+Char="O",135,63,20,30,0,0
+Char="P",156,63,16,30,1,0
+Char="Q",173,63,20,30,0,0
+Char="R",194,63,15,30,1,0
+Char="S",210,63,13,30,1,-1
+Char="T",224,63,15,30,0,-1
+Char="U",1,94,16,30,1,1
+Char="V",18,94,17,30,0,0
+Char="W",36,94,25,30,0,0
+Char="X",62,94,15,30,0,0
+Char="Y",78,94,17,30,-1,0
+Char="Z",96,94,15,30,-1,0
+Char="[",112,94,9,30,1,0
+Char="\",122,94,8,30,0,0
+Char="]",131,94,9,30,0,1
+Char="^",141,94,13,30,0,0
+Char="_",155,94,14,30,-1,-1
+Char="`",170,94,9,30,0,0
+Char="a",180,94,15,30,0,0
+Char="b",196,94,15,30,0,0
+Char="c",212,94,11,30,0,0
+Char="d",224,94,15,30,0,0
+Char="e",240,94,13,30,0,0
+Char="f",1,125,10,30,-2,0
+Char="g",12,125,14,30,0,0
+Char="h",27,125,14,30,0,0
+Char="i",42,125,6,30,0,-1
+Char="j",49,125,8,30,-2,-1
+Char="k",58,125,15,30,0,0
+Char="l",74,125,5,30,0,0
+Char="m",80,125,21,30,0,0
+Char="n",102,125,14,30,0,0
+Char="o",117,125,14,30,0,0
+Char="p",132,125,15,30,0,0
+Char="q",148,125,15,30,0,0
+Char="r",164,125,10,30,0,-1
+Char="s",175,125,8,30,0,0
+Char="t",184,125,11,30,-2,0
+Char="u",196,125,15,30,0,0
+Char="v",212,125,13,30,0,0
+Char="w",226,125,21,30,0,-1
+Char="x",1,156,12,30,0,0
+Char="y",14,156,13,30,0,0
+Char="z",28,156,12,30,0,-1
+Char="{",41,156,10,30,0,-1
+Char="|",52,156,4,30,1,2
+Char="}",57,156,10,30,-1,0
+Char="~",68,156,15,30,-1,-1
diff --git a/archive/blr1/resources/credits.png b/archive/blr1/resources/credits.png Binary files differnew file mode 100644 index 0000000..14c2a49 --- /dev/null +++ b/archive/blr1/resources/credits.png diff --git a/archive/blr1/resources/ss1.png b/archive/blr1/resources/ss1.png Binary files differnew file mode 100644 index 0000000..19dd5c2 --- /dev/null +++ b/archive/blr1/resources/ss1.png diff --git a/archive/blr1/resources/ss2.png b/archive/blr1/resources/ss2.png Binary files differnew file mode 100644 index 0000000..5959cdf --- /dev/null +++ b/archive/blr1/resources/ss2.png diff --git a/archive/blr1/resources/tap.ogg b/archive/blr1/resources/tap.ogg Binary files differnew file mode 100644 index 0000000..1ef00b0 --- /dev/null +++ b/archive/blr1/resources/tap.ogg diff --git a/archive/blr1/resources/title.png b/archive/blr1/resources/title.png Binary files differnew file mode 100644 index 0000000..b4205c2 --- /dev/null +++ b/archive/blr1/resources/title.png diff --git a/archive/blr1/src/effects.h b/archive/blr1/src/effects.h new file mode 100644 index 0000000..044a803 --- /dev/null +++ b/archive/blr1/src/effects.h @@ -0,0 +1,88 @@ +//Chrisoft Bullet Lab Remix HGE
+//Effects Implementations
+//"Copyleft" Chrisoft 2013
+void SCEffect_Attatch()
+{
+ int cnt=rand()%8+3;
+ for (int ii=1;ii<=cnt;++ii)
+ {
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=254;
+ bullet[i].bulletpos.x=playerpos.x;
+ bullet[i].bulletpos.y=playerpos.y;
+ bullet[i].bulletdir.x=rand()%100-50;
+ bullet[i].bulletdir.y=rand()%100-50;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=rand()%4+2;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,46,0,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ }
+}
+void SCEffect_Process()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=254)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ ++effskp;
+ if (effskp==7)
+ bullet[i].bulletspr->SetColor(bullet[i].bulletspr->GetColor()-0x1F000000),effskp=0;
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ ++effskp;
+ if (effskp==7)
+ bullet[i].bulletspr->SetColor(bullet[i].bulletspr->GetColor()-0x1000000),effskp=0;
+ }
+ //bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ //bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (GETA(bullet[i].bulletspr->GetColor())<=0x0A||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x,bullet[i].bulletpos.y,0,0.2,0);
+ }
+ }
+
+}
+void BulletEffect_Attatch(int n)
+{
+ bullet[n].scale=2;
+ bullet[n].effbrk=17;
+}
+void BulletEffect_Process(int n)
+{
+ if (bullet[n].scale<=1){bullet[n].scale=1;return;}
+ if (LOWFPS)
+ bullet[n].effbrk-=17;
+ else
+ --bullet[n].effbrk;
+ if (bullet[n].effbrk<=0)
+ bullet[n].scale-=0.04,bullet[n].effbrk=17;
+}
\ No newline at end of file diff --git a/archive/blr1/src/global.h b/archive/blr1/src/global.h new file mode 100644 index 0000000..85804e8 --- /dev/null +++ b/archive/blr1/src/global.h @@ -0,0 +1,297 @@ +//Chrisoft Bullet Lab Remix HGE
+//Global varibles and implementations
+//"Copyleft" Chrisoft 2013
+#include "hge.h"
+#include "hgefont.h"
+#include "hgegui.h"
+HGE *hge=0;
+HEFFECT snd;
+HTEXTURE tex;
+hgeQuad quad;
+hgeGUI *gui;
+hgeFont *fnt;
+hgeSprite *spr,*titlespr;
+//Here are some Varibles in Bullet Lab
+int Current_Position;//Where are we now.
+/*Scenes:
+0: main menu
+1: game scene
+2: tip scene
+3: start menu
+4: about scene
+5: death scene
+6: complete scene
+7: new highscore scene
+8: highscore scene
+9: highscore view scene
+10: highscore details scene
+11: Pause scene
+12: BackToTitle Confirm
+13: Options scene
+14: Player Profile scene
+*/
+HTEXTURE SprSheet1,SprSheet2,TexTitle,TexCredits;
+/*
+Texture Mapping:
+SprSheet1:
+Player 47,46,24,24
+Cursor 24,46,24,24
+Blue 0,0,24,24
+Green 23,0,24,24
+Pnt 46,0,24,24
+Purple 0,23,24,24
+Red 23,23,24,24
+White 46,23,24,24
+Yellow 0,46,24,24
+SprSheet2:
+Blue 0,0,44,44
+Green 44,0,44,44
+Purple 88,0,44,44
+Red 0,44,44,44
+White 44,44,44,44
+Yellow 88,44,44,44
+*/
+const double zero=1e-3;
+struct vector2d
+{
+ double x,y;
+};
+struct Bullet
+{
+ hgeSprite *bulletspr;
+ vector2d bulletpos;
+ vector2d bulletdir;
+ double dist;
+ int bullettype;
+ int redexplo,redattrib,oriexplo,whicnt;
+ double bulletspeed;
+ bool exist;
+ double scale;
+ int whirem,whiskp,yelbrk;
+ int lifetime;
+ bool scollable;
+ int effbrk;
+}bullet[10000];
+//Something about bullets:
+//bullettype:
+//1: dir-based green bullet
+//2: degree-based blue bullet (for clocks only)
+//3: 12direction-based blue bullet
+//4: yellow chaser bullet
+//5: purple slow down bullet
+//6: red exploding bullet
+//7: white stalled bullet
+//8: black shading bullet (dummy in version 1)
+//254: Semi-collision effect
+//255: Score point
+struct Tower
+{
+ hgeSprite *towerspr;
+ vector2d towerpos;
+ int towertype;
+ int towertimer,curtimer;
+ double bulletspeed;
+ int redexplo,whicnt,yelbrk;
+ int t3t;
+ bool exist;
+ bool effect;
+}tower[100];
+//t3t is for Tower3
+//0:All 12 directions
+//1:four default directions
+//2:random left/right
+//3:random up/down
+struct Line
+{
+ vector2d pos;
+ double radian;
+ DWORD color;
+ bool exist;
+}line[12];
+//Line is currently dummy.
+int bulcnt=0,towcnt=0,linecnt=0;
+vector2d playerpos;
+double playerrot;
+double playerspeed;
+double playerslospeed;
+double playerfulspd=0.2;
+double playerfulslospd=0.05;
+double clockrot,deltarot,deltadelta;
+double whirot,dwhirot;
+hgeSprite *playerspr;
+int frameleft;
+int level,part,clrtime,clrbns;
+int coll,semicoll,mode,dsmc,restarts;
+double clrrange;
+bool IfCallLevel;
+bool DisableAllTower=false;
+bool DisablePlayer=false;
+int frameskips=0,stepskips=0;
+bool IfShowTip=false,FadeTip=false;
+hgeFont *TipFont;
+char lasttip[200];
+int p2t1,p2t2,p2t3,p2t4;
+int whicnt,shots,clrusg;
+bool yelattrib;
+bool LOWFPS=false,diffkey=false;
+bool Complete=false;
+bool Refliction=false;
+double linerad=0;
+double bsscale;
+long long score,scminus;
+int frms;double averfps;
+int plrspd,plrslospd;
+int TenSeconds=10000,TwentySeconds=20000,ThirtySeconds=30000,AMinute=60000;
+int effskp=0;
+hgeSprite *Credits,*CreditsRail;
+double scroll;
+bool tfs;
+int fpslvl;
+
+void Error(char EC[],bool hgecreated=false)
+{
+ fprintf(stderr,EC);
+ hge->System_Log(EC);
+ if (hgecreated)
+ {
+ hge->System_Shutdown();
+ hge->Release();
+ }
+ exit(0);
+}
+inline double GetDist(const vector2d a,const vector2d b)
+{
+ return sqrtf((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
+}
+void ShowTip(char tip[])
+{
+ if (strcmp(tip,lasttip)!=0)
+ {
+ TipFont->SetColor(0x00FFFFFF);
+ }
+ memcpy(lasttip,tip,sizeof(lasttip));
+ DisableAllTower=true;
+ DisablePlayer=true;
+ if (hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT)
+ {
+ //DisableAllTower=false;
+ //DisablePlayer=false;
+ //Current_Position=1;
+ FadeTip=true;
+ }
+ double width=TipFont->GetStringWidth(tip);
+ TipFont->printf(400-width/2,400,HGETEXT_LEFT,tip);
+ if (FadeTip)
+ {
+ if (LOWFPS)
+ {
+ if (TipFont->GetColor()>>24>=0x08)
+ TipFont->SetColor(TipFont->GetColor()-0x8000000);
+ else
+ {
+ DisableAllTower=false;
+ DisablePlayer=false;
+ Current_Position=1;
+ }
+ }
+ else
+ {
+ if (TipFont->GetColor()>>24>=0x01)
+ TipFont->SetColor(TipFont->GetColor()-0x1000000);
+ else
+ {
+ DisableAllTower=false;
+ DisablePlayer=false;
+ Current_Position=1;
+ }
+ }
+ return;
+ }
+ if (!LOWFPS)
+ {
+ if (TipFont->GetColor()>>24<=0xFE)
+ TipFont->SetColor(TipFont->GetColor()+0x01000000);
+ }
+ else
+ {
+ if (TipFont->GetColor()>>24<=0xF7)
+ TipFont->SetColor(TipFont->GetColor()+0x08000000);
+ }
+}
+void ClearAll()
+{
+ DisableAllTower=true;
+ bool none=true;
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)continue;
+ if (LOWFPS)
+ {
+ if (tower[i].towerspr->GetColor()>>24>=0x08)
+ {
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()-0x8000000);
+ none=false;
+ }
+ }
+ else
+ {
+ if (tower[i].towerspr->GetColor()>>24>=0x01)
+ {
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()-0x1000000);
+ none=false;
+ }
+ }
+ }
+ if (none)
+ {
+ towcnt=0;
+ memset(tower,0,sizeof(tower));
+ }
+ none=true;
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (LOWFPS)
+ {
+ if (bullet[i].bulletspr->GetColor()>>24>=0x08)
+ {
+ bullet[i].bulletspr->SetColor(bullet[i].bulletspr->GetColor()-0x8000000);
+ none=false;
+ }
+ }
+ else
+ {
+ if (bullet[i].bulletspr->GetColor()>>24>=0x01)
+ {
+ bullet[i].bulletspr->SetColor(bullet[i].bulletspr->GetColor()-0x1000000);
+ none=false;
+ }
+ }
+ }
+ if (none)
+ {
+ bulcnt=0;
+ memset(bullet,0,sizeof(bullet));
+ }
+ none=true;
+ for (int i=1;i<=bulcnt;++i)if (bullet[i].bulletspr->GetColor()>>24>=0x3F){none=false;break;}
+ if (none)
+ bulcnt=0,memset(bullet,0,sizeof(bullet));
+}
+void SaySomethingAndBye(char *text)
+{
+ ClearAll();
+ DisableAllTower=false;
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip(text);
+ return;
+ }
+ Current_Position=0;
+ towcnt=bulcnt=0;
+ memset(tower,0,sizeof(tower));
+ memset(bullet,0,sizeof(bullet));
+ gui->Enter();
+}
diff --git a/archive/blr1/src/levels.h b/archive/blr1/src/levels.h new file mode 100644 index 0000000..d706f4a --- /dev/null +++ b/archive/blr1/src/levels.h @@ -0,0 +1,1880 @@ +//Chrisoft Bullet Lab Remix HGE
+//Level Implementations
+//"Copyleft" Chrisoft 2013
+void Level1Part1()
+{
+ //Level procedure
+ //Simple Level procedures should only run once during a level, you know.
+ if ((tower[CreateTower1(400,300,2000,1)].towerspr->GetColor()>>24)>=0x80)IfCallLevel=false;
+ Current_Position=2;
+ ShowTip("Welcome to Bullet Lab Remix...\nMove around and hit nothing, easy right?\n\Press Z to close these tips.");
+}
+void Level1Part2()
+{
+ frameleft=TenSeconds;
+ ++frameskips;
+ int secondtower=CreateTower1(567,300,2000,1);
+ if (tower[secondtower].towerspr->GetColor()==0x80FFFFFF)
+ tower[secondtower].towerspr->SetColor(0x00FFFFFF);
+ if (frameskips<10&&!LOWFPS&&!LOWFPS)return;
+ frameskips=0;
+ if ((tower[secondtower].towerspr->GetColor()>>24)<=0x80)
+ tower[secondtower].towerspr->SetColor(tower[secondtower].towerspr->GetColor()+0x01FFFFFF);
+ if (tower[1].towerpos.x>=233)--tower[1].towerpos.x;
+ if (tower[1].towerpos.x<233)
+ {
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Want another tower?");
+ IfCallLevel=false;
+ }
+ }
+}
+void Level1Part3()
+{
+ frameleft=TenSeconds;
+ tower[1].bulletspeed=4;
+ tower[1].towertimer=1500;
+ tower[2].bulletspeed=4;
+ tower[2].towertimer=1500;
+ IfCallLevel=false;
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Maybe faster bullets will kill you?");
+ IfCallLevel=false;
+ }
+}
+void Level1Part4()
+{
+ frameleft=TenSeconds;
+ tower[1].bulletspeed=2;
+ tower[1].towertimer=100;
+ tower[2].bulletspeed=2;
+ tower[2].towertimer=100;
+ IfCallLevel=false;
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("There are two things to tell you.\nFirst one is that this game has very\
+ loose collision detection.\nNext one is two machineguns are ready for\
+ the next level...");
+ IfCallLevel=false;
+ }
+}
+void Level2Part0()
+{
+ frameleft=50;
+ if (towcnt==2)
+ {
+ ClearAll();
+ return;
+ }
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ DisableAllTower=false;
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Level 2 - Divide and Conquer!");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ p2t1=p2t2=p2t3=p2t4=0;
+ return;
+ }
+}
+void Level2Part1()
+{
+ frameleft=TwentySeconds;
+ if (p2t1==0)p2t1=CreateTower1(399,299,1000,2);
+ if (p2t2==0)p2t2=CreateTower1(401,299,1000,2);
+ if (p2t3==0)p2t3=CreateTower1(399,301,1000,2);
+ if (p2t4==0)p2t4=CreateTower1(401,301,1000,2);
+ bool none=true;
+ if (!LOWFPS)
+ {
+ if (tower[p2t1].towerpos.x>=10)tower[p2t1].towerpos.x-=0.4075,none=false;
+ if (tower[p2t1].towerpos.y>=10)tower[p2t1].towerpos.y-=0.3,none=false;
+ if (tower[p2t2].towerpos.x<=766)tower[p2t2].towerpos.x+=0.3813,none=false;
+ if (tower[p2t2].towerpos.y>=10)tower[p2t2].towerpos.y-=0.3,none=false;
+ if (tower[p2t3].towerpos.x>=10)tower[p2t3].towerpos.x-=0.4453125,none=false;
+ if (tower[p2t3].towerpos.y<=566)tower[p2t3].towerpos.y+=0.3,none=false;
+ if (tower[p2t4].towerpos.x<=766)tower[p2t4].towerpos.x+=0.455859,none=false;
+ if (tower[p2t4].towerpos.y<=566)tower[p2t4].towerpos.y+=0.3,none=false;
+ }
+ else
+ {
+ if (tower[p2t1].towerpos.x>=10)tower[p2t1].towerpos.x-=0.4075*10,none=false;
+ if (tower[p2t1].towerpos.y>=10)tower[p2t1].towerpos.y-=0.3*10,none=false;
+ if (tower[p2t2].towerpos.x<=766)tower[p2t2].towerpos.x+=0.3813*10,none=false;
+ if (tower[p2t2].towerpos.y>=10)tower[p2t2].towerpos.y-=0.3*10,none=false;
+ if (tower[p2t3].towerpos.x>=10)tower[p2t3].towerpos.x-=0.4453125*10,none=false;
+ if (tower[p2t3].towerpos.y<=566)tower[p2t3].towerpos.y+=0.3*10,none=false;
+ if (tower[p2t4].towerpos.x<=766)tower[p2t4].towerpos.x+=0.455859*10,none=false;
+ if (tower[p2t4].towerpos.y<=566)tower[p2t4].towerpos.y+=0.3*10,none=false;
+ }
+ if (none)IfCallLevel=false;
+}
+void Level2Part2()
+{
+ frameleft=TenSeconds;
+ tower[p2t1].bulletspeed=tower[p2t2].bulletspeed=4;
+ tower[p2t3].bulletspeed=tower[p2t4].bulletspeed=4;
+ IfCallLevel=false;
+}
+void Level2Part3()
+{
+ frameleft=ThirtySeconds;
+ tower[p2t1].bulletspeed=tower[p2t2].bulletspeed=1;
+ tower[p2t3].bulletspeed=tower[p2t4].bulletspeed=1;
+ tower[p2t1].towertimer=tower[p2t2].towertimer=100;
+ tower[p2t3].towertimer=tower[p2t4].towertimer=100;
+ IfCallLevel=false;
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Got ready for being hunted by four machineguns?\n\
+Don't tell me you've got stuck just here...");
+ IfCallLevel=false;
+ }
+}
+void Level3Part0()
+{
+ frameleft=50;
+ if (towcnt==4&&(mode!=2))
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ if (mode==2)
+ ShowTip("Let's start from a higher position...\n\
+Level 3 - Blue Masters");
+ else
+ ShowTip("Time for something new now...\n\
+Level 3 - Blue Masters");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ return;
+ }
+}
+void Level3Part1()
+{
+ frameleft=ThirtySeconds;
+ ++frameskips;
+ if (towcnt==4)towcnt=0;
+ deltadelta=0.004363322313;
+ int towerclk=CreateTower2(400,300,100,1,true);
+ if (tower[towerclk].towerspr->GetColor()==0x80FFFFFF)
+ tower[towerclk].towerspr->SetColor(0x00FFFFFF);
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ if ((tower[towerclk].towerspr->GetColor()>>24)<=0x80)
+ tower[towerclk].towerspr->SetColor(tower[towerclk].towerspr->GetColor()+0x01FFFFFF);
+ else IfCallLevel=false;
+}
+//L3P2: /*Magic, DO NOT TOUCH!!*/
+void Level3Part2()
+{
+ frameleft=TenSeconds;
+ if (towcnt==1)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Are you scared?\nI'm just joking last time!");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower1(233,300,500,2);
+ CreateTower1(567,300,500,2);
+ int tmp=CreateTower3(100,100,1000,1,true);
+ tower[tmp].t3t=1;
+ tmp=CreateTower3(300,100,1000,1,true);
+ tower[tmp].t3t=1;
+ tmp=CreateTower3(500,100,1000,1,true);
+ tower[tmp].t3t=1;
+ tmp=CreateTower3(700,100,1000,1,true);
+ tower[tmp].t3t=1;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level3Part3()
+{
+ frameleft=TwentySeconds;
+ if (towcnt==6&&IfShowTip)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Got stuck in my pentagon...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower3(30,10,500,2,true);
+ CreateTower3(746,10,500,2,true);
+ CreateTower3(30,556,500,2,true);
+ CreateTower3(746,556,500,2,true);
+ for (int i=1;i<=4;++i)
+ tower[i].t3t=0;
+ CreateTower1(5,10,1000,2);
+ CreateTower1(771,10,1000,2);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level3Part4()
+{
+ frameleft=TwentySeconds;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towertype==3)tower[i].towertimer=300;else tower[i].towertimer=500;
+ int aa=CreateTower1(5,556,500,2);
+ int bb=CreateTower1(771,556,500,2);
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ if (tower[aa].towerspr->GetColor()==0x80FFFFFF)
+ tower[aa].towerspr->SetColor(0x00FFFFFF);
+ if (tower[bb].towerspr->GetColor()==0x80FFFFFF)
+ tower[bb].towerspr->SetColor(0x00FFFFFF);
+ if ((tower[aa].towerspr->GetColor()>>24)<=0x80)
+ tower[aa].towerspr->SetColor(tower[aa].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+ if ((tower[bb].towerspr->GetColor()>>24)<=0x80)
+ tower[bb].towerspr->SetColor(tower[bb].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level3Part5()
+{
+ frameleft=ThirtySeconds;
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ for (int i=1;i<=4;++i)tower[i].t3t=1;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towertype==1)
+ tower[i].towertimer=750;
+ bool none=true;
+ if (tower[1].towerpos.x<=120)++tower[1].towerpos.x,none=false;
+ if (tower[1].towerpos.y<=80)++tower[1].towerpos.y,none=false;
+ if (tower[2].towerpos.x>=660)--tower[2].towerpos.x,none=false;
+ if (tower[2].towerpos.y<=80)++tower[2].towerpos.y,none=false;
+ if (tower[3].towerpos.x<=120)++tower[3].towerpos.x,none=false;
+ if (tower[3].towerpos.y>=480)--tower[3].towerpos.y,none=false;
+ if (tower[4].towerpos.x>=660)--tower[4].towerpos.x,none=false;
+ if (tower[4].towerpos.y>=480)--tower[4].towerpos.y,none=false;
+ if (none)IfCallLevel=false;
+}
+void Level3Part6()
+{
+ frameleft=ThirtySeconds;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towertype==1)
+ tower[i].towertimer=1000,tower[i].bulletspeed=6;
+ IfCallLevel=false;
+}
+void Level3Part7()
+{
+ frameleft=ThirtySeconds;
+ if (towcnt==8)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("This part will be a great fun if the green tower didn't exist...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower1(400,540,750,3);
+ for (int i=1;i<=33;++i)
+ {
+ int tmp=CreateTower3(i*24-20,570,300,2);
+ tower[tmp].t3t=3;
+ }
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level4Part0()
+{
+ frameleft=50;
+ if (towcnt==34)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Someone is following you.\n\
+Level 4 - At the Pet Store");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ return;
+ }
+}
+void Level4Part1()
+{
+ frameleft=TenSeconds;
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower4(400,300,2000,2);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level4Part2()
+{
+ frameleft=TwentySeconds;
+ if (towcnt==1)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("May be they are kittens petted by you?..");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower4(30,10,2000,1);
+ CreateTower4(746,10,2000,1);
+ CreateTower4(30,556,2000,1);
+ CreateTower4(746,556,2000,1);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level4Part3()
+{
+ frameleft=TenSeconds;
+ if (towcnt==4)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower3(30,10,300,2);
+ CreateTower3(746,10,300,2);
+ CreateTower3(30,556,300,2);
+ CreateTower3(746,556,300,2);
+ for (int i=1;i<=4;++i)
+ tower[i].t3t=1;
+ CreateTower4(5,10,2000,2);
+ CreateTower4(771,10,2000,2);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level4Part4()
+{
+ frameleft=TwentySeconds;
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ tower[5].towertimer=tower[6].towertimer=1500;
+ bool none=true;
+ if (tower[1].towerpos.x<=120)++tower[1].towerpos.x,none=false;
+ if (tower[1].towerpos.y<=80)++tower[1].towerpos.y,none=false;
+ if (tower[2].towerpos.x>=660)--tower[2].towerpos.x,none=false;
+ if (tower[2].towerpos.y<=80)++tower[2].towerpos.y,none=false;
+ if (tower[3].towerpos.x<=120)++tower[3].towerpos.x,none=false;
+ if (tower[3].towerpos.y>=480)--tower[3].towerpos.y,none=false;
+ if (tower[4].towerpos.x>=660)--tower[4].towerpos.x,none=false;
+ if (tower[4].towerpos.y>=480)--tower[4].towerpos.y,none=false;
+ if (none)IfCallLevel=false;
+}
+void Level4Part5()
+{
+ frameleft=ThirtySeconds;
+ if (towcnt==6)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Keep your rhythm!");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower3(30,10,300,2);
+ CreateTower3(746,10,300,2);
+ CreateTower3(30,556,300,2);
+ CreateTower3(746,556,300,2);
+ CreateTower3(400,10,300,2);
+ CreateTower3(400,556,300,2);
+ CreateTower4(6,10,2000,2);
+ CreateTower4(760,10,2000,2);
+ CreateTower4(6,556,2000,2);
+ CreateTower4(760,556,2000,2);
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ if (tower[i].towertype==3)
+ tower[i].t3t=1;
+ }
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+
+}
+void Level4Part6()
+{
+ frameleft=ThirtySeconds;
+ if (towcnt==10)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Play with a kitten in the maze?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower4(400,540,3000,2);
+ for (int i=1;i<=33;++i)
+ {
+ int tmp=CreateTower3(i*24-20,570,500,2);
+ tower[tmp].t3t=3;
+ }
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level5Part0()
+{
+ frameleft=50;
+ if (towcnt==34)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Bullets that kill you won't move so fast...\n\
+Level 5 - A Huge Joke");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ return;
+ }
+}
+void Level5Part1()
+{
+ frameleft=TenSeconds;
+ if (towcnt==8)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ int tmp=CreateTower5(i*24-20,30,200,10);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level5Part2()
+{
+ frameleft=TwentySeconds;
+ if (towcnt==33)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower1(233,300,750,4);
+ CreateTower1(567,300,750,4);
+ for (int i=1;i<=33;++i)
+ int tmp=CreateTower5(i*24-20,30,500,4);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level5Part3()
+{
+ frameleft=ThirtySeconds;
+ if (towcnt==35)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower4(400,300,1000,2);
+ for (int i=1;i<=33;++i)
+ int tmp=CreateTower5(i*24-20,30,500,4);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level5Part4()
+{
+ frameleft=ThirtySeconds;
+ if (towcnt==34)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Avoiding is no longer an option.");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ int tmp=CreateTower1(i*24-20,30,500,4);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part0()
+{
+ frameleft=50;
+ if (towcnt==33)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Now you are going to meet my ultimate fire power...\n\
+Level 6 - The Great Clock");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ return;
+ }
+}
+void Level6Part1()
+{
+ frameleft=TwentySeconds;clrtime=0;
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower6(400,300,1000,2,1000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part2()
+{
+ frameleft=ThirtySeconds;clrtime=5;
+ if (towcnt==1)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Let's test the Advanced Bullet Script...\n\
+From now on you can use your Clear Ranges, try pressing Z in game.");
+ }
+ if (Current_Position==1)
+ {
+ ++part;
+ }
+}
+int Level6Part3_Child()
+{
+ ++stepskips;
+ if (stepskips<100)return 0;
+ stepskips=0;
+ if (towcnt==1){towcnt=0;return 0;}
+ CreateTower6(rand()%800,rand()%300,50,2,500);
+ return 1;
+}
+void Level6Part3()
+{
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ if (Level6Part3_Child())
+ {
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ return;
+ }
+ }
+}
+void Level6Part4()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (bulcnt!=0||towcnt!=5&&towcnt!=0)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Last level was very cool, wasn't it?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower6(400,300,750,2,1000);
+ CreateTower6(30,10,750,2,1000);
+ CreateTower6(746,10,750,2,1000);
+ CreateTower6(30,556,750,2,1000);
+ CreateTower6(746,556,750,2,1000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part5()
+{
+ frameleft=ThirtySeconds;clrtime=5;
+ if (bulcnt!=0||towcnt!=33)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("A row of fierce red tower?...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ int tmp=CreateTower6(i*24-20,30,3000,2,1000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part6()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (bulcnt!=0||towcnt!=37)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Enjoy the same maze.");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower6(30,10,1500,2,1000);
+ CreateTower6(746,10,1500,2,1000);
+ CreateTower6(30,556,1500,2,1000);
+ CreateTower6(746,556,1500,2,1000);
+ for (int i=1;i<=33;++i)
+ {
+ int tmp=CreateTower3(i*24-20,570,1000,2,true);
+ tower[tmp].t3t=3;
+ }
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part7()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (towcnt==37)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("You are supposed to leave now...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower4(30,10,2000,2);
+ CreateTower4(746,10,2000,2);
+ CreateTower4(30,556,2000,2);
+ CreateTower4(746,556,2000,2);
+ CreateTower3(120,80,300,2);
+ CreateTower3(660,80,300,2);
+ CreateTower3(120,480,300,2);
+ CreateTower3(660,480,300,2);
+ CreateTower1(400,30,500,2);
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ if (tower[i].towertype==3)tower[i].t3t=1;
+ }
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part8()
+{
+ frameleft=ThirtySeconds;clrtime=1;
+ if (towcnt==9)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("I don't think you can pass this easily...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower1(30,10,300,2);
+ CreateTower1(746,10,300,2);
+ CreateTower1(30,556,300,2);
+ CreateTower1(746,556,300,2);
+ CreateTower4(400,30,3000,3);
+ CreateTower3(900,900,999999,1);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level6Part9()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (towcnt!=2&&towcnt!=0)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Okay you survived...\n\
+But that was nothing much, more bombs is always the answer!");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower2(400,300,100,1);
+ CreateTower6(400,301,2000,1,1500);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part0()
+{
+ frameleft=50;
+ if (towcnt==2||bulcnt!=0)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Some freezy small objects are getting nearer...\n\
+Level 7 - Frozen Towers");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ return;
+ }
+}
+void Level7Part1()
+{
+ frameleft=ThirtySeconds;clrtime=0;
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ whicnt=10;
+ CreateTower7(400,300,1000,2,3000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part2()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (bulcnt!=0||(towcnt!=5&&towcnt!=0))
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Is it horrifying?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ whicnt=8;
+ CreateTower7(400,300,2000,1,3000);
+ CreateTower7(30,10,2000,1,3000);
+ CreateTower7(746,10,2000,1,3000);
+ CreateTower7(30,556,2000,1,3000);
+ CreateTower7(746,556,2000,1,3000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part3()
+{
+ frameleft=ThirtySeconds;clrtime=5;
+ if (towcnt==5)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Red & White.\n\
+Bloody snow?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ whicnt=5;
+ for (int i=1;i<=33;++i)
+ if (i&1)
+ CreateTower6(i*24-20,30,3000,2,1000);
+ else
+ CreateTower7(i*24-20,30,3000,2,1000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part4()
+{
+ frameleft=ThirtySeconds;clrtime=0;
+ if (towcnt==33||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Or this is only a bonus level?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ CreateTower1(i*24-20,30,1000,4),CreateTower1(i*24-20,567,1000,4);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part5()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (towcnt==66||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Wasn't that enough?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ CreateTower1(i*24-20,30,500,4),CreateTower5(i*24-20,567,500,4);
+ CreateTower3(900,900,999999,1);//Dummy tower for avoiding mis-clearing
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part6()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (towcnt==67||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("The impossible thing happened in the end...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ if (i&1)
+ CreateTower6(i*24-20,30,3000,1,1500),CreateTower5(i*24-20,567,500,3);
+ else
+ CreateTower5(i*24-20,567,500,3);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part7()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (towcnt==50||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Do you think you are fooled?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ whicnt=3;
+ for (int i=1;i<=33;++i)
+ if (i&1)
+ CreateTower7(i*24-20,30,2000,1,2000),CreateTower5(i*24-20,567,500,3);
+ else
+ CreateTower5(i*24-20,567,500,3);
+ CreateTower3(900,900,999999,1);//Dummy tower
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+
+}
+void Level7Part8()
+{
+ frameleft=ThirtySeconds;clrtime=5;
+ if (towcnt==51)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("I won't let you go easily...\n\
+But why?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ whicnt=2;
+ for (int i=1;i<=33;++i)
+ if (i&1)
+ CreateTower6(400,30,3000,1,2000);//,CreateTower5(i*24-20,567,2000,3);
+ else
+ CreateTower1(i*24-20,567,2000,3);//,CreateTower7(i*24-20,30,3000,1,2000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part9()
+{
+ frameleft=TwentySeconds;clrtime=1;
+ if (towcnt!=5&&towcnt!=0)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Let's relax a bit...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ CreateTower1(400,30,300,2);
+ CreateTower6(30,10,1000,2,1000);
+ CreateTower6(746,10,1000,2,1000);
+ CreateTower6(30,556,1000,2,1000);
+ CreateTower6(746,556,1000,2,1000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+
+}
+void Level7Part10()
+{
+ frameleft=ThirtySeconds;clrtime=3;
+ if (towcnt==5)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("I still can't let you go...\n\
+Just play with me! (And enjoy the double laby!)");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ for (int i=1;i<=33;++i)
+ {
+ int tmp=CreateTower3(i*24-20,570,500,2);
+ tower[tmp].t3t=3;
+ }
+ for (int i=1;i<=23;++i)
+ {
+ int tmp=CreateTower3(772,i*24,500,2);
+ tower[tmp].t3t=2;
+ }
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part11()
+{
+ frameleft=AMinute;clrtime=3;
+ if ((towcnt!=5&&towcnt!=0)||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("You will be full of holes after this level...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ whicnt=50;
+ CreateTower7(400,30,3000,1,3000);
+ CreateTower6(30,10,2000,1,2000);
+ CreateTower6(746,10,2000,1,2000);
+ CreateTower6(30,556,2000,1,2000);
+ CreateTower6(746,556,2000,1,2000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level7Part12()
+{
+ frameleft=AMinute;clrtime=3;
+ if ((towcnt!=6&&towcnt!=0)||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Well, here it is.");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ whicnt=50;
+ CreateTower7(400,30,3000,1,3000);
+ CreateTower6(400,300,2000,1,1500);
+ CreateTower1(30,10,2000,2);
+ CreateTower1(746,10,2000,2);
+ CreateTower1(30,556,2000,2);
+ CreateTower1(746,556,2000,2);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+
+}
+void Level8Part0()
+{
+ frameleft=50;
+ if (towcnt==6)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Welcome to the world that is only known by...masochism\n\
+Level 8 - Entertainment!");
+ IfCallLevel=false;
+ }
+ if (Current_Position==1)
+ {
+ frameleft=0;
+ return;
+ }
+}
+void Level8Part1()
+{
+ frameleft=ThirtySeconds;clrtime=0;
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower7(400,300,2500,8,750);
+ whicnt=25;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+
+}
+void Level8Part2()
+{
+ frameleft=TenSeconds;clrtime=3;
+ if (towcnt!=2&&bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Just another joke?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ deltadelta=0.004363322313/4;
+ CreateTower2(420,60,100,3);
+ CreateTower2(380,60,100,3);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level8Part3()
+{
+ frameleft=TenSeconds;
+ CreateTower2(460,100,100,3);
+ CreateTower2(340,100,100,3);
+ deltadelta=0.004363322313/8;
+ IfCallLevel=false;
+}
+void Level8Part4()
+{
+ frameleft=TenSeconds;
+ CreateTower2(500,140,100,3);
+ CreateTower2(300,140,100,3);
+ deltadelta=0.004363322313/16;
+ IfCallLevel=false;
+}
+void Level8Part5()
+{
+ frameleft=ThirtySeconds;clrtime=1;
+ if (towcnt==6||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("They are not cute enough to follow you all the time...");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ yelattrib=true;
+ for (int i=1;i<=33;++i)
+ int tmp=CreateTower4(i*24-20,30,2000,4,2000);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level8Part6()
+{
+ frameleft=AMinute;clrtime=3;
+ clrtime=3;
+ if (towcnt==33||(bulcnt!=0&&towcnt!=4))
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Hope you can enjoy... the entertaining level\n\
+Are they bullets or other object?");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower1(30,10,20,10);
+ CreateTower1(746,10,20,10);
+ CreateTower1(30,556,20,10);
+ CreateTower1(746,556,20,10);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level8Part7()
+{
+ frameleft=ThirtySeconds;clrtime=5;
+ if (towcnt==4||bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Nautilus!");
+ }
+ if (Current_Position==1)
+ {
+ ++part;
+ }
+}
+int Level8Part8_Child()
+{
+ ++stepskips;
+ if (stepskips<2)return 0;
+ stepskips=0;
+ linerad+=0.05;
+ for (int i=1;;++i)
+ {
+ double tx=400+sin(linerad)*i*12;
+ double ty=300+cos(linerad)*i*12;
+ if (tx>800||tx<0||ty>600||ty<0)
+ {
+ hge->Gfx_RenderLine(400,300,tx,ty,0x80CCFF00);
+ break;
+ }
+ int bult=CreateBullet1(tx,ty,1);
+ bullet[bult].bulletdir.x=-sin(linerad/*-1.5707963268*/);
+ bullet[bult].bulletdir.y=-cos(linerad/*-1.5707963268*/);
+ bullet[bult].dist=bullet[bult].bulletdir.x*bullet[bult].bulletdir.x+bullet[bult].bulletdir.y*bullet[bult].bulletdir.y;
+ bullet[bult].dist=sqrt(bullet[bult].dist);
+ }
+ return 1;
+}
+void Level8Part8()
+{
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ frameskips=0;
+ if (Level8Part8_Child())
+ {
+ }
+}
+void Level8Part9()
+{
+ frameleft=AMinute;clrtime=5;
+ if (bulcnt!=0&&towcnt!=2)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Two towers means too much");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower6(380,60,1000,8,1000);
+ CreateTower7(420,60,1000,8,750);
+ whicnt=16;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level8Part10()
+{
+ frameleft=AMinute;clrtime=5;
+ if (towcnt==2)
+ {
+ ClearAll();
+ return;
+ }
+ DisableAllTower=false;
+ bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Well, here is the final mixture.\n\
+Enjoy it!");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ CreateTower4(30,10,2000,2,3000);
+ CreateTower4(746,10,2000,2,3000);
+ CreateTower4(30,556,2000,2,3000);
+ CreateTower4(746,556,2000,2,3000);
+ CreateTower3(120,80,300,2);
+ CreateTower3(660,80,300,2);
+ CreateTower3(120,480,300,2);
+ CreateTower3(660,480,300,2);
+ CreateTower1(400,30,500,2);
+ CreateTower6(380,60,1000,6,1000);
+ CreateTower7(420,60,1000,6,750);
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towertype==3)
+ tower[i].t3t=1;
+ yelattrib=true;
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
+void Level8Part11()
+{
+ frameleft=AMinute;
+ if (towcnt!=1&&bulcnt!=0)
+ {
+ ClearAll();
+ if (bulcnt!=0||towcnt!=0)return;
+ }
+ DisableAllTower=false;
+ towcnt=0;bulcnt=0;memset(bullet,0,sizeof(bullet));
+ if (IfShowTip)
+ {
+ IfShowTip=false;
+ FadeTip=false;
+ Current_Position=2;
+ ShowTip("Addition Level: Reflection++\n\
+Give yourself an award even if you cannot pass this level.");
+ return;
+ }
+ ++frameskips;
+ if (frameskips<10&&!LOWFPS)return;
+ Refliction=true;
+ CreateTower6(400,566,1000,2,1000);
+ /*for (int i=1;i<=33;++i)
+ {
+ int tmp=CreateTower3(i*24-20,570,1000,2);
+ tower[tmp].t3t=3;
+ }
+ for (int i=1;i<=23;++i)
+ {
+ int tmp=CreateTower3(772,i*24,1000,2);
+ tower[tmp].t3t=2;
+ }*/
+ for (int i=1;i<=towcnt;++i)
+ if (tower[i].towerspr->GetColor()==0x80FFFFFF)
+ tower[i].towerspr->SetColor(0x00FFFFFF);
+ for (int i=1;i<=towcnt;++i)
+ if ((tower[i].towerspr->GetColor()>>24)<=0x80)
+ tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF);
+ else
+ {
+ IfCallLevel=false;
+ return;
+ }
+}
\ No newline at end of file diff --git a/archive/blr1/src/loading.h b/archive/blr1/src/loading.h new file mode 100644 index 0000000..acf59aa --- /dev/null +++ b/archive/blr1/src/loading.h @@ -0,0 +1,384 @@ +unsigned char Loading[]= +{0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x60, +0x00,0x00,0x00,0x20,0x08,0x06,0x00,0x00,0x00,0xED,0xC0,0x7D,0x54,0x00,0x00,0x00,0x09,0x70,0x48, +0x59,0x73,0x00,0x00,0x0B,0x13,0x00,0x00,0x0B,0x13,0x01,0x00,0x9A,0x9C,0x18,0x00,0x00,0x0A,0x4D, +0x69,0x43,0x43,0x50,0x50,0x68,0x6F,0x74,0x6F,0x73,0x68,0x6F,0x70,0x20,0x49,0x43,0x43,0x20,0x70, +0x72,0x6F,0x66,0x69,0x6C,0x65,0x00,0x00,0x78,0xDA,0x9D,0x53,0x77,0x58,0x93,0xF7,0x16,0x3E,0xDF, +0xF7,0x65,0x0F,0x56,0x42,0xD8,0xF0,0xB1,0x97,0x6C,0x81,0x00,0x22,0x23,0xAC,0x08,0xC8,0x10,0x59, +0xA2,0x10,0x92,0x00,0x61,0x84,0x10,0x12,0x40,0xC5,0x85,0x88,0x0A,0x56,0x14,0x15,0x11,0x9C,0x48, +0x55,0xC4,0x82,0xD5,0x0A,0x48,0x9D,0x88,0xE2,0xA0,0x28,0xB8,0x67,0x41,0x8A,0x88,0x5A,0x8B,0x55, +0x5C,0x38,0xEE,0x1F,0xDC,0xA7,0xB5,0x7D,0x7A,0xEF,0xED,0xED,0xFB,0xD7,0xFB,0xBC,0xE7,0x9C,0xE7, +0xFC,0xCE,0x79,0xCF,0x0F,0x80,0x11,0x12,0x26,0x91,0xE6,0xA2,0x6A,0x00,0x39,0x52,0x85,0x3C,0x3A, +0xD8,0x1F,0x8F,0x4F,0x48,0xC4,0xC9,0xBD,0x80,0x02,0x15,0x48,0xE0,0x04,0x20,0x10,0xE6,0xCB,0xC2, +0x67,0x05,0xC5,0x00,0x00,0xF0,0x03,0x79,0x78,0x7E,0x74,0xB0,0x3F,0xFC,0x01,0xAF,0x6F,0x00,0x02, +0x00,0x70,0xD5,0x2E,0x24,0x12,0xC7,0xE1,0xFF,0x83,0xBA,0x50,0x26,0x57,0x00,0x20,0x91,0x00,0xE0, +0x22,0x12,0xE7,0x0B,0x01,0x90,0x52,0x00,0xC8,0x2E,0x54,0xC8,0x14,0x00,0xC8,0x18,0x00,0xB0,0x53, +0xB3,0x64,0x0A,0x00,0x94,0x00,0x00,0x6C,0x79,0x7C,0x42,0x22,0x00,0xAA,0x0D,0x00,0xEC,0xF4,0x49, +0x3E,0x05,0x00,0xD8,0xA9,0x93,0xDC,0x17,0x00,0xD8,0xA2,0x1C,0xA9,0x08,0x00,0x8D,0x01,0x00,0x99, +0x28,0x47,0x24,0x02,0x40,0xBB,0x00,0x60,0x55,0x81,0x52,0x2C,0x02,0xC0,0xC2,0x00,0xA0,0xAC,0x40, +0x22,0x2E,0x04,0xC0,0xAE,0x01,0x80,0x59,0xB6,0x32,0x47,0x02,0x80,0xBD,0x05,0x00,0x76,0x8E,0x58, +0x90,0x0F,0x40,0x60,0x00,0x80,0x99,0x42,0x2C,0xCC,0x00,0x20,0x38,0x02,0x00,0x43,0x1E,0x13,0xCD, +0x03,0x20,0x4C,0x03,0xA0,0x30,0xD2,0xBF,0xE0,0xA9,0x5F,0x70,0x85,0xB8,0x48,0x01,0x00,0xC0,0xCB, +0x95,0xCD,0x97,0x4B,0xD2,0x33,0x14,0xB8,0x95,0xD0,0x1A,0x77,0xF2,0xF0,0xE0,0xE2,0x21,0xE2,0xC2, +0x6C,0xB1,0x42,0x61,0x17,0x29,0x10,0x66,0x09,0xE4,0x22,0x9C,0x97,0x9B,0x23,0x13,0x48,0xE7,0x03, +0x4C,0xCE,0x0C,0x00,0x00,0x1A,0xF9,0xD1,0xC1,0xFE,0x38,0x3F,0x90,0xE7,0xE6,0xE4,0xE1,0xE6,0x66, +0xE7,0x6C,0xEF,0xF4,0xC5,0xA2,0xFE,0x6B,0xF0,0x6F,0x22,0x3E,0x21,0xF1,0xDF,0xFE,0xBC,0x8C,0x02, +0x04,0x00,0x10,0x4E,0xCF,0xEF,0xDA,0x5F,0xE5,0xE5,0xD6,0x03,0x70,0xC7,0x01,0xB0,0x75,0xBF,0x6B, +0xA9,0x5B,0x00,0xDA,0x56,0x00,0x68,0xDF,0xF9,0x5D,0x33,0xDB,0x09,0xA0,0x5A,0x0A,0xD0,0x7A,0xF9, +0x8B,0x79,0x38,0xFC,0x40,0x1E,0x9E,0xA1,0x50,0xC8,0x3C,0x1D,0x1C,0x0A,0x0B,0x0B,0xED,0x25,0x62, +0xA1,0xBD,0x30,0xE3,0x8B,0x3E,0xFF,0x33,0xE1,0x6F,0xE0,0x8B,0x7E,0xF6,0xFC,0x40,0x1E,0xFE,0xDB, +0x7A,0xF0,0x00,0x71,0x9A,0x40,0x99,0xAD,0xC0,0xA3,0x83,0xFD,0x71,0x61,0x6E,0x76,0xAE,0x52,0x8E, +0xE7,0xCB,0x04,0x42,0x31,0x6E,0xF7,0xE7,0x23,0xFE,0xC7,0x85,0x7F,0xFD,0x8E,0x29,0xD1,0xE2,0x34, +0xB1,0x5C,0x2C,0x15,0x8A,0xF1,0x58,0x89,0xB8,0x50,0x22,0x4D,0xC7,0x79,0xB9,0x52,0x91,0x44,0x21, +0xC9,0x95,0xE2,0x12,0xE9,0x7F,0x32,0xF1,0x1F,0x96,0xFD,0x09,0x93,0x77,0x0D,0x00,0xAC,0x86,0x4F, +0xC0,0x4E,0xB6,0x07,0xB5,0xCB,0x6C,0xC0,0x7E,0xEE,0x01,0x02,0x8B,0x0E,0x58,0xD2,0x76,0x00,0x40, +0x7E,0xF3,0x2D,0x8C,0x1A,0x0B,0x91,0x00,0x10,0x67,0x34,0x32,0x79,0xF7,0x00,0x00,0x93,0xBF,0xF9, +0x8F,0x40,0x2B,0x01,0x00,0xCD,0x97,0xA4,0xE3,0x00,0x00,0xBC,0xE8,0x18,0x5C,0xA8,0x94,0x17,0x4C, +0xC6,0x08,0x00,0x00,0x44,0xA0,0x81,0x2A,0xB0,0x41,0x07,0x0C,0xC1,0x14,0xAC,0xC0,0x0E,0x9C,0xC1, +0x1D,0xBC,0xC0,0x17,0x02,0x61,0x06,0x44,0x40,0x0C,0x24,0xC0,0x3C,0x10,0x42,0x06,0xE4,0x80,0x1C, +0x0A,0xA1,0x18,0x96,0x41,0x19,0x54,0xC0,0x3A,0xD8,0x04,0xB5,0xB0,0x03,0x1A,0xA0,0x11,0x9A,0xE1, +0x10,0xB4,0xC1,0x31,0x38,0x0D,0xE7,0xE0,0x12,0x5C,0x81,0xEB,0x70,0x17,0x06,0x60,0x18,0x9E,0xC2, +0x18,0xBC,0x86,0x09,0x04,0x41,0xC8,0x08,0x13,0x61,0x21,0x3A,0x88,0x11,0x62,0x8E,0xD8,0x22,0xCE, +0x08,0x17,0x99,0x8E,0x04,0x22,0x61,0x48,0x34,0x92,0x80,0xA4,0x20,0xE9,0x88,0x14,0x51,0x22,0xC5, +0xC8,0x72,0xA4,0x02,0xA9,0x42,0x6A,0x91,0x5D,0x48,0x23,0xF2,0x2D,0x72,0x14,0x39,0x8D,0x5C,0x40, +0xFA,0x90,0xDB,0xC8,0x20,0x32,0x8A,0xFC,0x8A,0xBC,0x47,0x31,0x94,0x81,0xB2,0x51,0x03,0xD4,0x02, +0x75,0x40,0xB9,0xA8,0x1F,0x1A,0x8A,0xC6,0xA0,0x73,0xD1,0x74,0x34,0x0F,0x5D,0x80,0x96,0xA2,0x6B, +0xD1,0x1A,0xB4,0x1E,0x3D,0x80,0xB6,0xA2,0xA7,0xD1,0x4B,0xE8,0x75,0x74,0x00,0x7D,0x8A,0x8E,0x63, +0x80,0xD1,0x31,0x0E,0x66,0x8C,0xD9,0x61,0x5C,0x8C,0x87,0x45,0x60,0x89,0x58,0x1A,0x26,0xC7,0x16, +0x63,0xE5,0x58,0x35,0x56,0x8F,0x35,0x63,0x1D,0x58,0x37,0x76,0x15,0x1B,0xC0,0x9E,0x61,0xEF,0x08, +0x24,0x02,0x8B,0x80,0x13,0xEC,0x08,0x5E,0x84,0x10,0xC2,0x6C,0x82,0x90,0x90,0x47,0x58,0x4C,0x58, +0x43,0xA8,0x25,0xEC,0x23,0xB4,0x12,0xBA,0x08,0x57,0x09,0x83,0x84,0x31,0xC2,0x27,0x22,0x93,0xA8, +0x4F,0xB4,0x25,0x7A,0x12,0xF9,0xC4,0x78,0x62,0x3A,0xB1,0x90,0x58,0x46,0xAC,0x26,0xEE,0x21,0x1E, +0x21,0x9E,0x25,0x5E,0x27,0x0E,0x13,0x5F,0x93,0x48,0x24,0x0E,0xC9,0x92,0xE4,0x4E,0x0A,0x21,0x25, +0x90,0x32,0x49,0x0B,0x49,0x6B,0x48,0xDB,0x48,0x2D,0xA4,0x53,0xA4,0x3E,0xD2,0x10,0x69,0x9C,0x4C, +0x26,0xEB,0x90,0x6D,0xC9,0xDE,0xE4,0x08,0xB2,0x80,0xAC,0x20,0x97,0x91,0xB7,0x90,0x0F,0x90,0x4F, +0x92,0xFB,0xC9,0xC3,0xE4,0xB7,0x14,0x3A,0xC5,0x88,0xE2,0x4C,0x09,0xA2,0x24,0x52,0xA4,0x94,0x12, +0x4A,0x35,0x65,0x3F,0xE5,0x04,0xA5,0x9F,0x32,0x42,0x99,0xA0,0xAA,0x51,0xCD,0xA9,0x9E,0xD4,0x08, +0xAA,0x88,0x3A,0x9F,0x5A,0x49,0x6D,0xA0,0x76,0x50,0x2F,0x53,0x87,0xA9,0x13,0x34,0x75,0x9A,0x25, +0xCD,0x9B,0x16,0x43,0xCB,0xA4,0x2D,0xA3,0xD5,0xD0,0x9A,0x69,0x67,0x69,0xF7,0x68,0x2F,0xE9,0x74, +0xBA,0x09,0xDD,0x83,0x1E,0x45,0x97,0xD0,0x97,0xD2,0x6B,0xE8,0x07,0xE9,0xE7,0xE9,0x83,0xF4,0x77, +0x0C,0x0D,0x86,0x0D,0x83,0xC7,0x48,0x62,0x28,0x19,0x6B,0x19,0x7B,0x19,0xA7,0x18,0xB7,0x19,0x2F, +0x99,0x4C,0xA6,0x05,0xD3,0x97,0x99,0xC8,0x54,0x30,0xD7,0x32,0x1B,0x99,0x67,0x98,0x0F,0x98,0x6F, +0x55,0x58,0x2A,0xF6,0x2A,0x7C,0x15,0x91,0xCA,0x12,0x95,0x3A,0x95,0x56,0x95,0x7E,0x95,0xE7,0xAA, +0x54,0x55,0x73,0x55,0x3F,0xD5,0x79,0xAA,0x0B,0x54,0xAB,0x55,0x0F,0xAB,0x5E,0x56,0x7D,0xA6,0x46, +0x55,0xB3,0x50,0xE3,0xA9,0x09,0xD4,0x16,0xAB,0xD5,0xA9,0x1D,0x55,0xBB,0xA9,0x36,0xAE,0xCE,0x52, +0x77,0x52,0x8F,0x50,0xCF,0x51,0x5F,0xA3,0xBE,0x5F,0xFD,0x82,0xFA,0x63,0x0D,0xB2,0x86,0x85,0x46, +0xA0,0x86,0x48,0xA3,0x54,0x63,0xB7,0xC6,0x19,0x8D,0x21,0x16,0xC6,0x32,0x65,0xF1,0x58,0x42,0xD6, +0x72,0x56,0x03,0xEB,0x2C,0x6B,0x98,0x4D,0x62,0x5B,0xB2,0xF9,0xEC,0x4C,0x76,0x05,0xFB,0x1B,0x76, +0x2F,0x7B,0x4C,0x53,0x43,0x73,0xAA,0x66,0xAC,0x66,0x91,0x66,0x9D,0xE6,0x71,0xCD,0x01,0x0E,0xC6, +0xB1,0xE0,0xF0,0x39,0xD9,0x9C,0x4A,0xCE,0x21,0xCE,0x0D,0xCE,0x7B,0x2D,0x03,0x2D,0x3F,0x2D,0xB1, +0xD6,0x6A,0xAD,0x66,0xAD,0x7E,0xAD,0x37,0xDA,0x7A,0xDA,0xBE,0xDA,0x62,0xED,0x72,0xED,0x16,0xED, +0xEB,0xDA,0xEF,0x75,0x70,0x9D,0x40,0x9D,0x2C,0x9D,0xF5,0x3A,0x6D,0x3A,0xF7,0x75,0x09,0xBA,0x36, +0xBA,0x51,0xBA,0x85,0xBA,0xDB,0x75,0xCF,0xEA,0x3E,0xD3,0x63,0xEB,0x79,0xE9,0x09,0xF5,0xCA,0xF5, +0x0E,0xE9,0xDD,0xD1,0x47,0xF5,0x6D,0xF4,0xA3,0xF5,0x17,0xEA,0xEF,0xD6,0xEF,0xD1,0x1F,0x37,0x30, +0x34,0x08,0x36,0x90,0x19,0x6C,0x31,0x38,0x63,0xF0,0xCC,0x90,0x63,0xE8,0x6B,0x98,0x69,0xB8,0xD1, +0xF0,0x84,0xE1,0xA8,0x11,0xCB,0x68,0xBA,0x91,0xC4,0x68,0xA3,0xD1,0x49,0xA3,0x27,0xB8,0x26,0xEE, +0x87,0x67,0xE3,0x35,0x78,0x17,0x3E,0x66,0xAC,0x6F,0x1C,0x62,0xAC,0x34,0xDE,0x65,0xDC,0x6B,0x3C, +0x61,0x62,0x69,0x32,0xDB,0xA4,0xC4,0xA4,0xC5,0xE4,0xBE,0x29,0xCD,0x94,0x6B,0x9A,0x66,0xBA,0xD1, +0xB4,0xD3,0x74,0xCC,0xCC,0xC8,0x2C,0xDC,0xAC,0xD8,0xAC,0xC9,0xEC,0x8E,0x39,0xD5,0x9C,0x6B,0x9E, +0x61,0xBE,0xD9,0xBC,0xDB,0xFC,0x8D,0x85,0xA5,0x45,0x9C,0xC5,0x4A,0x8B,0x36,0x8B,0xC7,0x96,0xDA, +0x96,0x7C,0xCB,0x05,0x96,0x4D,0x96,0xF7,0xAC,0x98,0x56,0x3E,0x56,0x79,0x56,0xF5,0x56,0xD7,0xAC, +0x49,0xD6,0x5C,0xEB,0x2C,0xEB,0x6D,0xD6,0x57,0x6C,0x50,0x1B,0x57,0x9B,0x0C,0x9B,0x3A,0x9B,0xCB, +0xB6,0xA8,0xAD,0x9B,0xAD,0xC4,0x76,0x9B,0x6D,0xDF,0x14,0xE2,0x14,0x8F,0x29,0xD2,0x29,0xF5,0x53, +0x6E,0xDA,0x31,0xEC,0xFC,0xEC,0x0A,0xEC,0x9A,0xEC,0x06,0xED,0x39,0xF6,0x61,0xF6,0x25,0xF6,0x6D, +0xF6,0xCF,0x1D,0xCC,0x1C,0x12,0x1D,0xD6,0x3B,0x74,0x3B,0x7C,0x72,0x74,0x75,0xCC,0x76,0x6C,0x70, +0xBC,0xEB,0xA4,0xE1,0x34,0xC3,0xA9,0xC4,0xA9,0xC3,0xE9,0x57,0x67,0x1B,0x67,0xA1,0x73,0x9D,0xF3, +0x35,0x17,0xA6,0x4B,0x90,0xCB,0x12,0x97,0x76,0x97,0x17,0x53,0x6D,0xA7,0x8A,0xA7,0x6E,0x9F,0x7A, +0xCB,0x95,0xE5,0x1A,0xEE,0xBA,0xD2,0xB5,0xD3,0xF5,0xA3,0x9B,0xBB,0x9B,0xDC,0xAD,0xD9,0x6D,0xD4, +0xDD,0xCC,0x3D,0xC5,0x7D,0xAB,0xFB,0x4D,0x2E,0x9B,0x1B,0xC9,0x5D,0xC3,0x3D,0xEF,0x41,0xF4,0xF0, +0xF7,0x58,0xE2,0x71,0xCC,0xE3,0x9D,0xA7,0x9B,0xA7,0xC2,0xF3,0x90,0xE7,0x2F,0x5E,0x76,0x5E,0x59, +0x5E,0xFB,0xBD,0x1E,0x4F,0xB3,0x9C,0x26,0x9E,0xD6,0x30,0x6D,0xC8,0xDB,0xC4,0x5B,0xE0,0xBD,0xCB, +0x7B,0x60,0x3A,0x3E,0x3D,0x65,0xFA,0xCE,0xE9,0x03,0x3E,0xC6,0x3E,0x02,0x9F,0x7A,0x9F,0x87,0xBE, +0xA6,0xBE,0x22,0xDF,0x3D,0xBE,0x23,0x7E,0xD6,0x7E,0x99,0x7E,0x07,0xFC,0x9E,0xFB,0x3B,0xFA,0xCB, +0xFD,0x8F,0xF8,0xBF,0xE1,0x79,0xF2,0x16,0xF1,0x4E,0x05,0x60,0x01,0xC1,0x01,0xE5,0x01,0xBD,0x81, +0x1A,0x81,0xB3,0x03,0x6B,0x03,0x1F,0x04,0x99,0x04,0xA5,0x07,0x35,0x05,0x8D,0x05,0xBB,0x06,0x2F, +0x0C,0x3E,0x15,0x42,0x0C,0x09,0x0D,0x59,0x1F,0x72,0x93,0x6F,0xC0,0x17,0xF2,0x1B,0xF9,0x63,0x33, +0xDC,0x67,0x2C,0x9A,0xD1,0x15,0xCA,0x08,0x9D,0x15,0x5A,0x1B,0xFA,0x30,0xCC,0x26,0x4C,0x1E,0xD6, +0x11,0x8E,0x86,0xCF,0x08,0xDF,0x10,0x7E,0x6F,0xA6,0xF9,0x4C,0xE9,0xCC,0xB6,0x08,0x88,0xE0,0x47, +0x6C,0x88,0xB8,0x1F,0x69,0x19,0x99,0x17,0xF9,0x7D,0x14,0x29,0x2A,0x32,0xAA,0x2E,0xEA,0x51,0xB4, +0x53,0x74,0x71,0x74,0xF7,0x2C,0xD6,0xAC,0xE4,0x59,0xFB,0x67,0xBD,0x8E,0xF1,0x8F,0xA9,0x8C,0xB9, +0x3B,0xDB,0x6A,0xB6,0x72,0x76,0x67,0xAC,0x6A,0x6C,0x52,0x6C,0x63,0xEC,0x9B,0xB8,0x80,0xB8,0xAA, +0xB8,0x81,0x78,0x87,0xF8,0x45,0xF1,0x97,0x12,0x74,0x13,0x24,0x09,0xED,0x89,0xE4,0xC4,0xD8,0xC4, +0x3D,0x89,0xE3,0x73,0x02,0xE7,0x6C,0x9A,0x33,0x9C,0xE4,0x9A,0x54,0x96,0x74,0x63,0xAE,0xE5,0xDC, +0xA2,0xB9,0x17,0xE6,0xE9,0xCE,0xCB,0x9E,0x77,0x3C,0x59,0x35,0x59,0x90,0x7C,0x38,0x85,0x98,0x12, +0x97,0xB2,0x3F,0xE5,0x83,0x20,0x42,0x50,0x2F,0x18,0x4F,0xE5,0xA7,0x6E,0x4D,0x1D,0x13,0xF2,0x84, +0x9B,0x85,0x4F,0x45,0xBE,0xA2,0x8D,0xA2,0x51,0xB1,0xB7,0xB8,0x4A,0x3C,0x92,0xE6,0x9D,0x56,0x95, +0xF6,0x38,0xDD,0x3B,0x7D,0x43,0xFA,0x68,0x86,0x4F,0x46,0x75,0xC6,0x33,0x09,0x4F,0x52,0x2B,0x79, +0x91,0x19,0x92,0xB9,0x23,0xF3,0x4D,0x56,0x44,0xD6,0xDE,0xAC,0xCF,0xD9,0x71,0xD9,0x2D,0x39,0x94, +0x9C,0x94,0x9C,0xA3,0x52,0x0D,0x69,0x96,0xB4,0x2B,0xD7,0x30,0xB7,0x28,0xB7,0x4F,0x66,0x2B,0x2B, +0x93,0x0D,0xE4,0x79,0xE6,0x6D,0xCA,0x1B,0x93,0x87,0xCA,0xF7,0xE4,0x23,0xF9,0x73,0xF3,0xDB,0x15, +0x6C,0x85,0x4C,0xD1,0xA3,0xB4,0x52,0xAE,0x50,0x0E,0x16,0x4C,0x2F,0xA8,0x2B,0x78,0x5B,0x18,0x5B, +0x78,0xB8,0x48,0xBD,0x48,0x5A,0xD4,0x33,0xDF,0x66,0xFE,0xEA,0xF9,0x23,0x0B,0x82,0x16,0x7C,0xBD, +0x90,0xB0,0x50,0xB8,0xB0,0xB3,0xD8,0xB8,0x78,0x59,0xF1,0xE0,0x22,0xBF,0x45,0xBB,0x16,0x23,0x8B, +0x53,0x17,0x77,0x2E,0x31,0x5D,0x52,0xBA,0x64,0x78,0x69,0xF0,0xD2,0x7D,0xCB,0x68,0xCB,0xB2,0x96, +0xFD,0x50,0xE2,0x58,0x52,0x55,0xF2,0x6A,0x79,0xDC,0xF2,0x8E,0x52,0x83,0xD2,0xA5,0xA5,0x43,0x2B, +0x82,0x57,0x34,0x95,0xA9,0x94,0xC9,0xCB,0x6E,0xAE,0xF4,0x5A,0xB9,0x63,0x15,0x61,0x95,0x64,0x55, +0xEF,0x6A,0x97,0xD5,0x5B,0x56,0x7F,0x2A,0x17,0x95,0x5F,0xAC,0x70,0xAC,0xA8,0xAE,0xF8,0xB0,0x46, +0xB8,0xE6,0xE2,0x57,0x4E,0x5F,0xD5,0x7C,0xF5,0x79,0x6D,0xDA,0xDA,0xDE,0x4A,0xB7,0xCA,0xED,0xEB, +0x48,0xEB,0xA4,0xEB,0x6E,0xAC,0xF7,0x59,0xBF,0xAF,0x4A,0xBD,0x6A,0x41,0xD5,0xD0,0x86,0xF0,0x0D, +0xAD,0x1B,0xF1,0x8D,0xE5,0x1B,0x5F,0x6D,0x4A,0xDE,0x74,0xA1,0x7A,0x6A,0xF5,0x8E,0xCD,0xB4,0xCD, +0xCA,0xCD,0x03,0x35,0x61,0x35,0xED,0x5B,0xCC,0xB6,0xAC,0xDB,0xF2,0xA1,0x36,0xA3,0xF6,0x7A,0x9D, +0x7F,0x5D,0xCB,0x56,0xFD,0xAD,0xAB,0xB7,0xBE,0xD9,0x26,0xDA,0xD6,0xBF,0xDD,0x77,0x7B,0xF3,0x0E, +0x83,0x1D,0x15,0x3B,0xDE,0xEF,0x94,0xEC,0xBC,0xB5,0x2B,0x78,0x57,0x6B,0xBD,0x45,0x7D,0xF5,0x6E, +0xD2,0xEE,0x82,0xDD,0x8F,0x1A,0x62,0x1B,0xBA,0xBF,0xE6,0x7E,0xDD,0xB8,0x47,0x77,0x4F,0xC5,0x9E, +0x8F,0x7B,0xA5,0x7B,0x07,0xF6,0x45,0xEF,0xEB,0x6A,0x74,0x6F,0x6C,0xDC,0xAF,0xBF,0xBF,0xB2,0x09, +0x6D,0x52,0x36,0x8D,0x1E,0x48,0x3A,0x70,0xE5,0x9B,0x80,0x6F,0xDA,0x9B,0xED,0x9A,0x77,0xB5,0x70, +0x5A,0x2A,0x0E,0xC2,0x41,0xE5,0xC1,0x27,0xDF,0xA6,0x7C,0x7B,0xE3,0x50,0xE8,0xA1,0xCE,0xC3,0xDC, +0xC3,0xCD,0xDF,0x99,0x7F,0xB7,0xF5,0x08,0xEB,0x48,0x79,0x2B,0xD2,0x3A,0xBF,0x75,0xAC,0x2D,0xA3, +0x6D,0xA0,0x3D,0xA1,0xBD,0xEF,0xE8,0x8C,0xA3,0x9D,0x1D,0x5E,0x1D,0x47,0xBE,0xB7,0xFF,0x7E,0xEF, +0x31,0xE3,0x63,0x75,0xC7,0x35,0x8F,0x57,0x9E,0xA0,0x9D,0x28,0x3D,0xF1,0xF9,0xE4,0x82,0x93,0xE3, +0xA7,0x64,0xA7,0x9E,0x9D,0x4E,0x3F,0x3D,0xD4,0x99,0xDC,0x79,0xF7,0x4C,0xFC,0x99,0x6B,0x5D,0x51, +0x5D,0xBD,0x67,0x43,0xCF,0x9E,0x3F,0x17,0x74,0xEE,0x4C,0xB7,0x5F,0xF7,0xC9,0xF3,0xDE,0xE7,0x8F, +0x5D,0xF0,0xBC,0x70,0xF4,0x22,0xF7,0x62,0xDB,0x25,0xB7,0x4B,0xAD,0x3D,0xAE,0x3D,0x47,0x7E,0x70, +0xFD,0xE1,0x48,0xAF,0x5B,0x6F,0xEB,0x65,0xF7,0xCB,0xED,0x57,0x3C,0xAE,0x74,0xF4,0x4D,0xEB,0x3B, +0xD1,0xEF,0xD3,0x7F,0xFA,0x6A,0xC0,0xD5,0x73,0xD7,0xF8,0xD7,0x2E,0x5D,0x9F,0x79,0xBD,0xEF,0xC6, +0xEC,0x1B,0xB7,0x6E,0x26,0xDD,0x1C,0xB8,0x25,0xBA,0xF5,0xF8,0x76,0xF6,0xED,0x17,0x77,0x0A,0xEE, +0x4C,0xDC,0x5D,0x7A,0x8F,0x78,0xAF,0xFC,0xBE,0xDA,0xFD,0xEA,0x07,0xFA,0x0F,0xEA,0x7F,0xB4,0xFE, +0xB1,0x65,0xC0,0x6D,0xE0,0xF8,0x60,0xC0,0x60,0xCF,0xC3,0x59,0x0F,0xEF,0x0E,0x09,0x87,0x9E,0xFE, +0x94,0xFF,0xD3,0x87,0xE1,0xD2,0x47,0xCC,0x47,0xD5,0x23,0x46,0x23,0x8D,0x8F,0x9D,0x1F,0x1F,0x1B, +0x0D,0x1A,0xBD,0xF2,0x64,0xCE,0x93,0xE1,0xA7,0xB2,0xA7,0x13,0xCF,0xCA,0x7E,0x56,0xFF,0x79,0xEB, +0x73,0xAB,0xE7,0xDF,0xFD,0xE2,0xFB,0x4B,0xCF,0x58,0xFC,0xD8,0xF0,0x0B,0xF9,0x8B,0xCF,0xBF,0xAE, +0x79,0xA9,0xF3,0x72,0xEF,0xAB,0xA9,0xAF,0x3A,0xC7,0x23,0xC7,0x1F,0xBC,0xCE,0x79,0x3D,0xF1,0xA6, +0xFC,0xAD,0xCE,0xDB,0x7D,0xEF,0xB8,0xEF,0xBA,0xDF,0xC7,0xBD,0x1F,0x99,0x28,0xFC,0x40,0xFE,0x50, +0xF3,0xD1,0xFA,0x63,0xC7,0xA7,0xD0,0x4F,0xF7,0x3E,0xE7,0x7C,0xFE,0xFC,0x2F,0xF7,0x84,0xF3,0xFB, +0x25,0xD2,0x9F,0x33,0x00,0x00,0x00,0x20,0x63,0x48,0x52,0x4D,0x00,0x00,0x7A,0x25,0x00,0x00,0x80, +0x83,0x00,0x00,0xF9,0xFF,0x00,0x00,0x80,0xE9,0x00,0x00,0x75,0x30,0x00,0x00,0xEA,0x60,0x00,0x00, +0x3A,0x98,0x00,0x00,0x17,0x6F,0x92,0x5F,0xC5,0x46,0x00,0x00,0x03,0x40,0x49,0x44,0x41,0x54,0x78, +0xDA,0xEC,0x5A,0xED,0x71,0xE2,0x40,0x0C,0x7D,0x64,0xEE,0x3F,0x7B,0x15,0x9C,0xAF,0x82,0x38,0x15, +0x9C,0xA9,0xE0,0xA0,0x82,0x90,0x0A,0xC2,0x55,0x00,0x54,0xC0,0xA5,0x02,0xE8,0xC0,0x50,0x81,0x49, +0x05,0x71,0x07,0xB8,0x03,0x7C,0x15,0xE8,0xFE,0x68,0x27,0x42,0xD1,0x62,0xC2,0x67,0x48,0xF6,0xCD, +0x78,0x6C,0xCB,0xFB,0xA1,0x5D,0xAD,0xA4,0xB7,0x0B,0x2D,0x22,0x42,0xC4,0xE5,0x70,0x13,0xA7,0x20, +0x1A,0x20,0x1A,0x20,0x22,0x1A,0x20,0x1A,0x20,0xE2,0x32,0xF8,0xC6,0x77,0x07,0x20,0xE5,0xE7,0x8A, +0xAF,0x6B,0x80,0xD7,0x3B,0x05,0x50,0x03,0x98,0x5D,0xAB,0x07,0xA4,0x00,0x0A,0xBE,0xEE,0xAF,0x48, +0x7F,0xAF,0xF7,0x44,0xE9,0xDD,0x07,0x30,0x60,0x03,0x5D,0x85,0x07,0x7C,0x26,0xF4,0x01,0x4C,0xF9, +0xF9,0x16,0xC0,0x43,0xCC,0x01,0xE7,0x0F,0x4B,0xD6,0x73,0xF4,0x80,0x33,0xE1,0x2F,0xDF,0xDB,0x00, +0x9E,0xBE,0x8A,0x01,0x64,0x12,0x5F,0x9E,0xA0,0xBC,0x47,0xC6,0xF7,0x92,0x93,0xAE,0x44,0x69,0x18, +0x61,0x57,0x3D,0x6A,0x55,0x7F,0x17,0x7D,0x53,0x96,0x2F,0x0F,0x9A,0x39,0x22,0x02,0x11,0x65,0xF4, +0x8A,0x21,0xCB,0x76,0xB9,0x52,0x22,0x2A,0xE8,0x2D,0xA6,0x44,0xE4,0x8C,0xF2,0x09,0x11,0xE5,0xAA, +0xEC,0x9A,0x88,0x06,0xFC,0x7D,0x25,0xEA,0xFB,0x3A,0x8E,0x88,0x26,0x46,0x1F,0xC3,0x80,0xDE,0x21, +0x59,0xC1,0x7D,0x65,0xDC,0xE6,0x54,0xB5,0xB7,0xE2,0xF1,0x40,0xF5,0x3D,0x35,0xF4,0xED,0xAA,0x71, +0x67,0xEF,0x98,0xB3,0x8D,0xEB,0x10,0x0F,0xF0,0x0C,0xC4,0x05,0x12,0x61,0x0A,0xA0,0x23,0x56,0x6A, +0x02,0xE0,0xC5,0x28,0xEF,0x98,0xC5,0xB4,0xB9,0x0C,0x14,0x0D,0x2E,0xC4,0xEA,0x93,0x18,0x35,0xAC, +0x5A,0xDD,0x87,0xF7,0x9E,0x47,0x7E,0xD6,0x7A,0x24,0x00,0x72,0x00,0x3F,0x85,0x2C,0x17,0xF5,0x64, +0x5B,0xF9,0xB1,0xA8,0xFA,0xCD,0x01,0x21,0x27,0xE7,0x7B,0xCD,0x4C,0xA3,0x05,0xE0,0x3B,0x4F,0x8C, +0x37,0xD0,0x54,0xD4,0x99,0x8A,0x41,0xCF,0x79,0xA0,0x2D,0x36,0x52,0x29,0xEA,0x49,0x0C,0xC5,0xE4, +0x97,0x5C,0xB6,0xC5,0x75,0xE7,0x01,0xC3,0x58,0x90,0xE1,0xAA,0xCB,0xEF,0x1D,0xD1,0xBF,0x5C,0x24, +0xA9,0x58,0x44,0x32,0xE4,0xDD,0x71,0xF9,0x3B,0x7E,0x4F,0x8E,0x12,0xBC,0xF7,0x0C,0x41,0x7D,0x51, +0xBE,0x6B,0x7C,0x97,0x21,0x23,0xE1,0x4B,0xBA,0xBA,0x15,0x9A,0xD6,0x86,0x4B,0xAF,0x55,0x3B,0xBA, +0xDE,0x6A,0xC7,0x10,0x04,0xD5,0xBF,0xDB,0xA2,0xAF,0xEF,0xBB,0xD8,0xD2,0x77,0xA2,0xC2,0xD2,0xDE, +0x21,0x68,0x5F,0x0F,0xF8,0x2D,0x42,0xC5,0xDC,0xF8,0xFE,0xA4,0x56,0x5C,0x57,0xBC,0x8F,0x8D,0xF2, +0x56,0x3B,0xA9,0xF0,0x98,0x59,0xC0,0xE5,0xC7,0x7B,0xE8,0x5E,0x19,0x09,0xBC,0x6E,0x48,0xF8,0x95, +0xD1,0x46,0xA9,0xDE,0xCF,0xCA,0x82,0x5C,0x43,0xC7,0x52,0xDE,0xDE,0xF2,0x6D,0x9B,0xDC,0xED,0x51, +0xE7,0x14,0xA8,0x77,0x90,0x57,0xE7,0xCE,0x01,0x4D,0x1B,0x1D,0xF7,0x01,0xEA,0x1C,0x8A,0x4A,0x78, +0x82,0xDB,0x92,0xD4,0x2F,0x92,0x84,0x17,0x22,0x4C,0x58,0x8A,0x3C,0xAA,0xB2,0xCF,0x81,0x6F,0x72, +0x40,0x7D,0x25,0x5B,0x2A,0x56,0x65,0x4D,0xF6,0x29,0xCF,0xAD,0x64,0x48,0x9C,0x88,0xFE,0x3D,0x6B, +0x3B,0xFB,0x51,0x84,0xB7,0x7A,0xC2,0x31,0xB9,0x16,0xCA,0x25,0x2A,0x76,0x0E,0xC4,0x24,0x96,0x7C, +0xAF,0x8C,0xEF,0x72,0x40,0x72,0x82,0x7F,0x89,0xD8,0xAF,0x59,0x97,0xC7,0x40,0xE5,0x96,0x63,0x63, +0x2C,0xC6,0xD8,0x07,0xB0,0x62,0x4A,0xBC,0x32,0x16,0x8B,0x64,0x7A,0x64,0xB0,0x3F,0x2D,0xDB,0xCA, +0x82,0x9A,0x30,0x34,0x98,0x10,0x31,0x6B,0x78,0x51,0x1B,0x96,0x54,0x6D,0xDA,0xF4,0xC6,0xA7,0x10, +0x4C,0x67,0x6D,0xF4,0xE1,0x94,0x7C,0xCD,0x75,0x56,0xA2,0x0D,0x52,0x9B,0xB7,0x26,0x16,0x54,0x18, +0x6C,0x64,0x18,0x60,0x34,0xA9,0xEA,0xC3,0x23,0x57,0x63,0xB5,0xE6,0x30,0x0B,0xC8,0x0E,0x66,0x41, +0xFF,0xC4,0xEA,0x7C,0x10,0xAB,0x24,0xC3,0xE6,0x6F,0x0A,0x1D,0xC5,0x14,0x4A,0x83,0x73,0xFB,0xF8, +0x3A,0x02,0xD0,0x0B,0x24,0x3A,0xD9,0x8E,0xF6,0xC2,0x3F,0x6A,0x23,0x75,0x6C,0x94,0xBC,0xE7,0xE8, +0xB1,0x8E,0x23,0xDE,0x07,0xF4,0x8C,0x5C,0x21,0xD9,0x55,0x8D,0xD7,0xDF,0x55,0xB4,0x6C,0x03,0x2D, +0xFE,0x5B,0x8A,0xDB,0x71,0x53,0x93,0x70,0x6C,0xAC,0x8D,0xD0,0x74,0xCB,0xEF,0xCF,0x0D,0xE7,0x23, +0x8E,0x43,0xC7,0x0F,0x36,0xE6,0x5C,0x85,0xA7,0x2A,0xC0,0x2A,0xBA,0xA2,0x8F,0x85,0x30,0x4A,0x26, +0x06,0x58,0x22,0xFC,0xE3,0x92,0x2E,0xA7,0xC7,0x95,0x18,0xE7,0x4C,0x43,0x96,0x2F,0x78,0x4C,0x35, +0xBF,0xDF,0x8B,0x8D,0xE3,0x4C,0x1C,0x79,0xA7,0x4C,0xD1,0xA5,0x7E,0x96,0xEC,0x8D,0x01,0x22,0x6C, +0xE4,0x0D,0x79,0xA6,0x66,0x8F,0xB8,0x18,0x0D,0xFD,0xEC,0x18,0x07,0x36,0x9A,0x9E,0x60,0x74,0x0E, +0xDD,0x8B,0x44,0x0F,0x78,0xFF,0x51,0x78,0xE8,0x38,0x3C,0x1A,0xE0,0x1A,0x11,0x43,0x50,0x34,0x40, +0x34,0x40,0x44,0x34,0xC0,0xD7,0xC5,0xFF,0x01,0x00,0xCC,0x01,0x97,0x8B,0x00,0x58,0xE9,0x5F,0x00, +0x00,0x00,0x00,0x49,0x45,0x4E,0x44,0xAE,0x42,0x60,0x82}; +unsigned char LoadCircle[]= +{0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x30, +0x00,0x00,0x00,0x2E,0x08,0x06,0x00,0x00,0x00,0x6E,0xDE,0x9A,0x6C,0x00,0x00,0x00,0x09,0x70,0x48, +0x59,0x73,0x00,0x00,0x0B,0x13,0x00,0x00,0x0B,0x13,0x01,0x00,0x9A,0x9C,0x18,0x00,0x00,0x0A,0x4D, +0x69,0x43,0x43,0x50,0x50,0x68,0x6F,0x74,0x6F,0x73,0x68,0x6F,0x70,0x20,0x49,0x43,0x43,0x20,0x70, +0x72,0x6F,0x66,0x69,0x6C,0x65,0x00,0x00,0x78,0xDA,0x9D,0x53,0x77,0x58,0x93,0xF7,0x16,0x3E,0xDF, +0xF7,0x65,0x0F,0x56,0x42,0xD8,0xF0,0xB1,0x97,0x6C,0x81,0x00,0x22,0x23,0xAC,0x08,0xC8,0x10,0x59, +0xA2,0x10,0x92,0x00,0x61,0x84,0x10,0x12,0x40,0xC5,0x85,0x88,0x0A,0x56,0x14,0x15,0x11,0x9C,0x48, +0x55,0xC4,0x82,0xD5,0x0A,0x48,0x9D,0x88,0xE2,0xA0,0x28,0xB8,0x67,0x41,0x8A,0x88,0x5A,0x8B,0x55, +0x5C,0x38,0xEE,0x1F,0xDC,0xA7,0xB5,0x7D,0x7A,0xEF,0xED,0xED,0xFB,0xD7,0xFB,0xBC,0xE7,0x9C,0xE7, +0xFC,0xCE,0x79,0xCF,0x0F,0x80,0x11,0x12,0x26,0x91,0xE6,0xA2,0x6A,0x00,0x39,0x52,0x85,0x3C,0x3A, +0xD8,0x1F,0x8F,0x4F,0x48,0xC4,0xC9,0xBD,0x80,0x02,0x15,0x48,0xE0,0x04,0x20,0x10,0xE6,0xCB,0xC2, +0x67,0x05,0xC5,0x00,0x00,0xF0,0x03,0x79,0x78,0x7E,0x74,0xB0,0x3F,0xFC,0x01,0xAF,0x6F,0x00,0x02, +0x00,0x70,0xD5,0x2E,0x24,0x12,0xC7,0xE1,0xFF,0x83,0xBA,0x50,0x26,0x57,0x00,0x20,0x91,0x00,0xE0, +0x22,0x12,0xE7,0x0B,0x01,0x90,0x52,0x00,0xC8,0x2E,0x54,0xC8,0x14,0x00,0xC8,0x18,0x00,0xB0,0x53, +0xB3,0x64,0x0A,0x00,0x94,0x00,0x00,0x6C,0x79,0x7C,0x42,0x22,0x00,0xAA,0x0D,0x00,0xEC,0xF4,0x49, +0x3E,0x05,0x00,0xD8,0xA9,0x93,0xDC,0x17,0x00,0xD8,0xA2,0x1C,0xA9,0x08,0x00,0x8D,0x01,0x00,0x99, +0x28,0x47,0x24,0x02,0x40,0xBB,0x00,0x60,0x55,0x81,0x52,0x2C,0x02,0xC0,0xC2,0x00,0xA0,0xAC,0x40, +0x22,0x2E,0x04,0xC0,0xAE,0x01,0x80,0x59,0xB6,0x32,0x47,0x02,0x80,0xBD,0x05,0x00,0x76,0x8E,0x58, +0x90,0x0F,0x40,0x60,0x00,0x80,0x99,0x42,0x2C,0xCC,0x00,0x20,0x38,0x02,0x00,0x43,0x1E,0x13,0xCD, +0x03,0x20,0x4C,0x03,0xA0,0x30,0xD2,0xBF,0xE0,0xA9,0x5F,0x70,0x85,0xB8,0x48,0x01,0x00,0xC0,0xCB, +0x95,0xCD,0x97,0x4B,0xD2,0x33,0x14,0xB8,0x95,0xD0,0x1A,0x77,0xF2,0xF0,0xE0,0xE2,0x21,0xE2,0xC2, +0x6C,0xB1,0x42,0x61,0x17,0x29,0x10,0x66,0x09,0xE4,0x22,0x9C,0x97,0x9B,0x23,0x13,0x48,0xE7,0x03, +0x4C,0xCE,0x0C,0x00,0x00,0x1A,0xF9,0xD1,0xC1,0xFE,0x38,0x3F,0x90,0xE7,0xE6,0xE4,0xE1,0xE6,0x66, +0xE7,0x6C,0xEF,0xF4,0xC5,0xA2,0xFE,0x6B,0xF0,0x6F,0x22,0x3E,0x21,0xF1,0xDF,0xFE,0xBC,0x8C,0x02, +0x04,0x00,0x10,0x4E,0xCF,0xEF,0xDA,0x5F,0xE5,0xE5,0xD6,0x03,0x70,0xC7,0x01,0xB0,0x75,0xBF,0x6B, +0xA9,0x5B,0x00,0xDA,0x56,0x00,0x68,0xDF,0xF9,0x5D,0x33,0xDB,0x09,0xA0,0x5A,0x0A,0xD0,0x7A,0xF9, +0x8B,0x79,0x38,0xFC,0x40,0x1E,0x9E,0xA1,0x50,0xC8,0x3C,0x1D,0x1C,0x0A,0x0B,0x0B,0xED,0x25,0x62, +0xA1,0xBD,0x30,0xE3,0x8B,0x3E,0xFF,0x33,0xE1,0x6F,0xE0,0x8B,0x7E,0xF6,0xFC,0x40,0x1E,0xFE,0xDB, +0x7A,0xF0,0x00,0x71,0x9A,0x40,0x99,0xAD,0xC0,0xA3,0x83,0xFD,0x71,0x61,0x6E,0x76,0xAE,0x52,0x8E, +0xE7,0xCB,0x04,0x42,0x31,0x6E,0xF7,0xE7,0x23,0xFE,0xC7,0x85,0x7F,0xFD,0x8E,0x29,0xD1,0xE2,0x34, +0xB1,0x5C,0x2C,0x15,0x8A,0xF1,0x58,0x89,0xB8,0x50,0x22,0x4D,0xC7,0x79,0xB9,0x52,0x91,0x44,0x21, +0xC9,0x95,0xE2,0x12,0xE9,0x7F,0x32,0xF1,0x1F,0x96,0xFD,0x09,0x93,0x77,0x0D,0x00,0xAC,0x86,0x4F, +0xC0,0x4E,0xB6,0x07,0xB5,0xCB,0x6C,0xC0,0x7E,0xEE,0x01,0x02,0x8B,0x0E,0x58,0xD2,0x76,0x00,0x40, +0x7E,0xF3,0x2D,0x8C,0x1A,0x0B,0x91,0x00,0x10,0x67,0x34,0x32,0x79,0xF7,0x00,0x00,0x93,0xBF,0xF9, +0x8F,0x40,0x2B,0x01,0x00,0xCD,0x97,0xA4,0xE3,0x00,0x00,0xBC,0xE8,0x18,0x5C,0xA8,0x94,0x17,0x4C, +0xC6,0x08,0x00,0x00,0x44,0xA0,0x81,0x2A,0xB0,0x41,0x07,0x0C,0xC1,0x14,0xAC,0xC0,0x0E,0x9C,0xC1, +0x1D,0xBC,0xC0,0x17,0x02,0x61,0x06,0x44,0x40,0x0C,0x24,0xC0,0x3C,0x10,0x42,0x06,0xE4,0x80,0x1C, +0x0A,0xA1,0x18,0x96,0x41,0x19,0x54,0xC0,0x3A,0xD8,0x04,0xB5,0xB0,0x03,0x1A,0xA0,0x11,0x9A,0xE1, +0x10,0xB4,0xC1,0x31,0x38,0x0D,0xE7,0xE0,0x12,0x5C,0x81,0xEB,0x70,0x17,0x06,0x60,0x18,0x9E,0xC2, +0x18,0xBC,0x86,0x09,0x04,0x41,0xC8,0x08,0x13,0x61,0x21,0x3A,0x88,0x11,0x62,0x8E,0xD8,0x22,0xCE, +0x08,0x17,0x99,0x8E,0x04,0x22,0x61,0x48,0x34,0x92,0x80,0xA4,0x20,0xE9,0x88,0x14,0x51,0x22,0xC5, +0xC8,0x72,0xA4,0x02,0xA9,0x42,0x6A,0x91,0x5D,0x48,0x23,0xF2,0x2D,0x72,0x14,0x39,0x8D,0x5C,0x40, +0xFA,0x90,0xDB,0xC8,0x20,0x32,0x8A,0xFC,0x8A,0xBC,0x47,0x31,0x94,0x81,0xB2,0x51,0x03,0xD4,0x02, +0x75,0x40,0xB9,0xA8,0x1F,0x1A,0x8A,0xC6,0xA0,0x73,0xD1,0x74,0x34,0x0F,0x5D,0x80,0x96,0xA2,0x6B, +0xD1,0x1A,0xB4,0x1E,0x3D,0x80,0xB6,0xA2,0xA7,0xD1,0x4B,0xE8,0x75,0x74,0x00,0x7D,0x8A,0x8E,0x63, +0x80,0xD1,0x31,0x0E,0x66,0x8C,0xD9,0x61,0x5C,0x8C,0x87,0x45,0x60,0x89,0x58,0x1A,0x26,0xC7,0x16, +0x63,0xE5,0x58,0x35,0x56,0x8F,0x35,0x63,0x1D,0x58,0x37,0x76,0x15,0x1B,0xC0,0x9E,0x61,0xEF,0x08, +0x24,0x02,0x8B,0x80,0x13,0xEC,0x08,0x5E,0x84,0x10,0xC2,0x6C,0x82,0x90,0x90,0x47,0x58,0x4C,0x58, +0x43,0xA8,0x25,0xEC,0x23,0xB4,0x12,0xBA,0x08,0x57,0x09,0x83,0x84,0x31,0xC2,0x27,0x22,0x93,0xA8, +0x4F,0xB4,0x25,0x7A,0x12,0xF9,0xC4,0x78,0x62,0x3A,0xB1,0x90,0x58,0x46,0xAC,0x26,0xEE,0x21,0x1E, +0x21,0x9E,0x25,0x5E,0x27,0x0E,0x13,0x5F,0x93,0x48,0x24,0x0E,0xC9,0x92,0xE4,0x4E,0x0A,0x21,0x25, +0x90,0x32,0x49,0x0B,0x49,0x6B,0x48,0xDB,0x48,0x2D,0xA4,0x53,0xA4,0x3E,0xD2,0x10,0x69,0x9C,0x4C, +0x26,0xEB,0x90,0x6D,0xC9,0xDE,0xE4,0x08,0xB2,0x80,0xAC,0x20,0x97,0x91,0xB7,0x90,0x0F,0x90,0x4F, +0x92,0xFB,0xC9,0xC3,0xE4,0xB7,0x14,0x3A,0xC5,0x88,0xE2,0x4C,0x09,0xA2,0x24,0x52,0xA4,0x94,0x12, +0x4A,0x35,0x65,0x3F,0xE5,0x04,0xA5,0x9F,0x32,0x42,0x99,0xA0,0xAA,0x51,0xCD,0xA9,0x9E,0xD4,0x08, +0xAA,0x88,0x3A,0x9F,0x5A,0x49,0x6D,0xA0,0x76,0x50,0x2F,0x53,0x87,0xA9,0x13,0x34,0x75,0x9A,0x25, +0xCD,0x9B,0x16,0x43,0xCB,0xA4,0x2D,0xA3,0xD5,0xD0,0x9A,0x69,0x67,0x69,0xF7,0x68,0x2F,0xE9,0x74, +0xBA,0x09,0xDD,0x83,0x1E,0x45,0x97,0xD0,0x97,0xD2,0x6B,0xE8,0x07,0xE9,0xE7,0xE9,0x83,0xF4,0x77, +0x0C,0x0D,0x86,0x0D,0x83,0xC7,0x48,0x62,0x28,0x19,0x6B,0x19,0x7B,0x19,0xA7,0x18,0xB7,0x19,0x2F, +0x99,0x4C,0xA6,0x05,0xD3,0x97,0x99,0xC8,0x54,0x30,0xD7,0x32,0x1B,0x99,0x67,0x98,0x0F,0x98,0x6F, +0x55,0x58,0x2A,0xF6,0x2A,0x7C,0x15,0x91,0xCA,0x12,0x95,0x3A,0x95,0x56,0x95,0x7E,0x95,0xE7,0xAA, +0x54,0x55,0x73,0x55,0x3F,0xD5,0x79,0xAA,0x0B,0x54,0xAB,0x55,0x0F,0xAB,0x5E,0x56,0x7D,0xA6,0x46, +0x55,0xB3,0x50,0xE3,0xA9,0x09,0xD4,0x16,0xAB,0xD5,0xA9,0x1D,0x55,0xBB,0xA9,0x36,0xAE,0xCE,0x52, +0x77,0x52,0x8F,0x50,0xCF,0x51,0x5F,0xA3,0xBE,0x5F,0xFD,0x82,0xFA,0x63,0x0D,0xB2,0x86,0x85,0x46, +0xA0,0x86,0x48,0xA3,0x54,0x63,0xB7,0xC6,0x19,0x8D,0x21,0x16,0xC6,0x32,0x65,0xF1,0x58,0x42,0xD6, +0x72,0x56,0x03,0xEB,0x2C,0x6B,0x98,0x4D,0x62,0x5B,0xB2,0xF9,0xEC,0x4C,0x76,0x05,0xFB,0x1B,0x76, +0x2F,0x7B,0x4C,0x53,0x43,0x73,0xAA,0x66,0xAC,0x66,0x91,0x66,0x9D,0xE6,0x71,0xCD,0x01,0x0E,0xC6, +0xB1,0xE0,0xF0,0x39,0xD9,0x9C,0x4A,0xCE,0x21,0xCE,0x0D,0xCE,0x7B,0x2D,0x03,0x2D,0x3F,0x2D,0xB1, +0xD6,0x6A,0xAD,0x66,0xAD,0x7E,0xAD,0x37,0xDA,0x7A,0xDA,0xBE,0xDA,0x62,0xED,0x72,0xED,0x16,0xED, +0xEB,0xDA,0xEF,0x75,0x70,0x9D,0x40,0x9D,0x2C,0x9D,0xF5,0x3A,0x6D,0x3A,0xF7,0x75,0x09,0xBA,0x36, +0xBA,0x51,0xBA,0x85,0xBA,0xDB,0x75,0xCF,0xEA,0x3E,0xD3,0x63,0xEB,0x79,0xE9,0x09,0xF5,0xCA,0xF5, +0x0E,0xE9,0xDD,0xD1,0x47,0xF5,0x6D,0xF4,0xA3,0xF5,0x17,0xEA,0xEF,0xD6,0xEF,0xD1,0x1F,0x37,0x30, +0x34,0x08,0x36,0x90,0x19,0x6C,0x31,0x38,0x63,0xF0,0xCC,0x90,0x63,0xE8,0x6B,0x98,0x69,0xB8,0xD1, +0xF0,0x84,0xE1,0xA8,0x11,0xCB,0x68,0xBA,0x91,0xC4,0x68,0xA3,0xD1,0x49,0xA3,0x27,0xB8,0x26,0xEE, +0x87,0x67,0xE3,0x35,0x78,0x17,0x3E,0x66,0xAC,0x6F,0x1C,0x62,0xAC,0x34,0xDE,0x65,0xDC,0x6B,0x3C, +0x61,0x62,0x69,0x32,0xDB,0xA4,0xC4,0xA4,0xC5,0xE4,0xBE,0x29,0xCD,0x94,0x6B,0x9A,0x66,0xBA,0xD1, +0xB4,0xD3,0x74,0xCC,0xCC,0xC8,0x2C,0xDC,0xAC,0xD8,0xAC,0xC9,0xEC,0x8E,0x39,0xD5,0x9C,0x6B,0x9E, +0x61,0xBE,0xD9,0xBC,0xDB,0xFC,0x8D,0x85,0xA5,0x45,0x9C,0xC5,0x4A,0x8B,0x36,0x8B,0xC7,0x96,0xDA, +0x96,0x7C,0xCB,0x05,0x96,0x4D,0x96,0xF7,0xAC,0x98,0x56,0x3E,0x56,0x79,0x56,0xF5,0x56,0xD7,0xAC, +0x49,0xD6,0x5C,0xEB,0x2C,0xEB,0x6D,0xD6,0x57,0x6C,0x50,0x1B,0x57,0x9B,0x0C,0x9B,0x3A,0x9B,0xCB, +0xB6,0xA8,0xAD,0x9B,0xAD,0xC4,0x76,0x9B,0x6D,0xDF,0x14,0xE2,0x14,0x8F,0x29,0xD2,0x29,0xF5,0x53, +0x6E,0xDA,0x31,0xEC,0xFC,0xEC,0x0A,0xEC,0x9A,0xEC,0x06,0xED,0x39,0xF6,0x61,0xF6,0x25,0xF6,0x6D, +0xF6,0xCF,0x1D,0xCC,0x1C,0x12,0x1D,0xD6,0x3B,0x74,0x3B,0x7C,0x72,0x74,0x75,0xCC,0x76,0x6C,0x70, +0xBC,0xEB,0xA4,0xE1,0x34,0xC3,0xA9,0xC4,0xA9,0xC3,0xE9,0x57,0x67,0x1B,0x67,0xA1,0x73,0x9D,0xF3, +0x35,0x17,0xA6,0x4B,0x90,0xCB,0x12,0x97,0x76,0x97,0x17,0x53,0x6D,0xA7,0x8A,0xA7,0x6E,0x9F,0x7A, +0xCB,0x95,0xE5,0x1A,0xEE,0xBA,0xD2,0xB5,0xD3,0xF5,0xA3,0x9B,0xBB,0x9B,0xDC,0xAD,0xD9,0x6D,0xD4, +0xDD,0xCC,0x3D,0xC5,0x7D,0xAB,0xFB,0x4D,0x2E,0x9B,0x1B,0xC9,0x5D,0xC3,0x3D,0xEF,0x41,0xF4,0xF0, +0xF7,0x58,0xE2,0x71,0xCC,0xE3,0x9D,0xA7,0x9B,0xA7,0xC2,0xF3,0x90,0xE7,0x2F,0x5E,0x76,0x5E,0x59, +0x5E,0xFB,0xBD,0x1E,0x4F,0xB3,0x9C,0x26,0x9E,0xD6,0x30,0x6D,0xC8,0xDB,0xC4,0x5B,0xE0,0xBD,0xCB, +0x7B,0x60,0x3A,0x3E,0x3D,0x65,0xFA,0xCE,0xE9,0x03,0x3E,0xC6,0x3E,0x02,0x9F,0x7A,0x9F,0x87,0xBE, +0xA6,0xBE,0x22,0xDF,0x3D,0xBE,0x23,0x7E,0xD6,0x7E,0x99,0x7E,0x07,0xFC,0x9E,0xFB,0x3B,0xFA,0xCB, +0xFD,0x8F,0xF8,0xBF,0xE1,0x79,0xF2,0x16,0xF1,0x4E,0x05,0x60,0x01,0xC1,0x01,0xE5,0x01,0xBD,0x81, +0x1A,0x81,0xB3,0x03,0x6B,0x03,0x1F,0x04,0x99,0x04,0xA5,0x07,0x35,0x05,0x8D,0x05,0xBB,0x06,0x2F, +0x0C,0x3E,0x15,0x42,0x0C,0x09,0x0D,0x59,0x1F,0x72,0x93,0x6F,0xC0,0x17,0xF2,0x1B,0xF9,0x63,0x33, +0xDC,0x67,0x2C,0x9A,0xD1,0x15,0xCA,0x08,0x9D,0x15,0x5A,0x1B,0xFA,0x30,0xCC,0x26,0x4C,0x1E,0xD6, +0x11,0x8E,0x86,0xCF,0x08,0xDF,0x10,0x7E,0x6F,0xA6,0xF9,0x4C,0xE9,0xCC,0xB6,0x08,0x88,0xE0,0x47, +0x6C,0x88,0xB8,0x1F,0x69,0x19,0x99,0x17,0xF9,0x7D,0x14,0x29,0x2A,0x32,0xAA,0x2E,0xEA,0x51,0xB4, +0x53,0x74,0x71,0x74,0xF7,0x2C,0xD6,0xAC,0xE4,0x59,0xFB,0x67,0xBD,0x8E,0xF1,0x8F,0xA9,0x8C,0xB9, +0x3B,0xDB,0x6A,0xB6,0x72,0x76,0x67,0xAC,0x6A,0x6C,0x52,0x6C,0x63,0xEC,0x9B,0xB8,0x80,0xB8,0xAA, +0xB8,0x81,0x78,0x87,0xF8,0x45,0xF1,0x97,0x12,0x74,0x13,0x24,0x09,0xED,0x89,0xE4,0xC4,0xD8,0xC4, +0x3D,0x89,0xE3,0x73,0x02,0xE7,0x6C,0x9A,0x33,0x9C,0xE4,0x9A,0x54,0x96,0x74,0x63,0xAE,0xE5,0xDC, +0xA2,0xB9,0x17,0xE6,0xE9,0xCE,0xCB,0x9E,0x77,0x3C,0x59,0x35,0x59,0x90,0x7C,0x38,0x85,0x98,0x12, +0x97,0xB2,0x3F,0xE5,0x83,0x20,0x42,0x50,0x2F,0x18,0x4F,0xE5,0xA7,0x6E,0x4D,0x1D,0x13,0xF2,0x84, +0x9B,0x85,0x4F,0x45,0xBE,0xA2,0x8D,0xA2,0x51,0xB1,0xB7,0xB8,0x4A,0x3C,0x92,0xE6,0x9D,0x56,0x95, +0xF6,0x38,0xDD,0x3B,0x7D,0x43,0xFA,0x68,0x86,0x4F,0x46,0x75,0xC6,0x33,0x09,0x4F,0x52,0x2B,0x79, +0x91,0x19,0x92,0xB9,0x23,0xF3,0x4D,0x56,0x44,0xD6,0xDE,0xAC,0xCF,0xD9,0x71,0xD9,0x2D,0x39,0x94, +0x9C,0x94,0x9C,0xA3,0x52,0x0D,0x69,0x96,0xB4,0x2B,0xD7,0x30,0xB7,0x28,0xB7,0x4F,0x66,0x2B,0x2B, +0x93,0x0D,0xE4,0x79,0xE6,0x6D,0xCA,0x1B,0x93,0x87,0xCA,0xF7,0xE4,0x23,0xF9,0x73,0xF3,0xDB,0x15, +0x6C,0x85,0x4C,0xD1,0xA3,0xB4,0x52,0xAE,0x50,0x0E,0x16,0x4C,0x2F,0xA8,0x2B,0x78,0x5B,0x18,0x5B, +0x78,0xB8,0x48,0xBD,0x48,0x5A,0xD4,0x33,0xDF,0x66,0xFE,0xEA,0xF9,0x23,0x0B,0x82,0x16,0x7C,0xBD, +0x90,0xB0,0x50,0xB8,0xB0,0xB3,0xD8,0xB8,0x78,0x59,0xF1,0xE0,0x22,0xBF,0x45,0xBB,0x16,0x23,0x8B, +0x53,0x17,0x77,0x2E,0x31,0x5D,0x52,0xBA,0x64,0x78,0x69,0xF0,0xD2,0x7D,0xCB,0x68,0xCB,0xB2,0x96, +0xFD,0x50,0xE2,0x58,0x52,0x55,0xF2,0x6A,0x79,0xDC,0xF2,0x8E,0x52,0x83,0xD2,0xA5,0xA5,0x43,0x2B, +0x82,0x57,0x34,0x95,0xA9,0x94,0xC9,0xCB,0x6E,0xAE,0xF4,0x5A,0xB9,0x63,0x15,0x61,0x95,0x64,0x55, +0xEF,0x6A,0x97,0xD5,0x5B,0x56,0x7F,0x2A,0x17,0x95,0x5F,0xAC,0x70,0xAC,0xA8,0xAE,0xF8,0xB0,0x46, +0xB8,0xE6,0xE2,0x57,0x4E,0x5F,0xD5,0x7C,0xF5,0x79,0x6D,0xDA,0xDA,0xDE,0x4A,0xB7,0xCA,0xED,0xEB, +0x48,0xEB,0xA4,0xEB,0x6E,0xAC,0xF7,0x59,0xBF,0xAF,0x4A,0xBD,0x6A,0x41,0xD5,0xD0,0x86,0xF0,0x0D, +0xAD,0x1B,0xF1,0x8D,0xE5,0x1B,0x5F,0x6D,0x4A,0xDE,0x74,0xA1,0x7A,0x6A,0xF5,0x8E,0xCD,0xB4,0xCD, +0xCA,0xCD,0x03,0x35,0x61,0x35,0xED,0x5B,0xCC,0xB6,0xAC,0xDB,0xF2,0xA1,0x36,0xA3,0xF6,0x7A,0x9D, +0x7F,0x5D,0xCB,0x56,0xFD,0xAD,0xAB,0xB7,0xBE,0xD9,0x26,0xDA,0xD6,0xBF,0xDD,0x77,0x7B,0xF3,0x0E, +0x83,0x1D,0x15,0x3B,0xDE,0xEF,0x94,0xEC,0xBC,0xB5,0x2B,0x78,0x57,0x6B,0xBD,0x45,0x7D,0xF5,0x6E, +0xD2,0xEE,0x82,0xDD,0x8F,0x1A,0x62,0x1B,0xBA,0xBF,0xE6,0x7E,0xDD,0xB8,0x47,0x77,0x4F,0xC5,0x9E, +0x8F,0x7B,0xA5,0x7B,0x07,0xF6,0x45,0xEF,0xEB,0x6A,0x74,0x6F,0x6C,0xDC,0xAF,0xBF,0xBF,0xB2,0x09, +0x6D,0x52,0x36,0x8D,0x1E,0x48,0x3A,0x70,0xE5,0x9B,0x80,0x6F,0xDA,0x9B,0xED,0x9A,0x77,0xB5,0x70, +0x5A,0x2A,0x0E,0xC2,0x41,0xE5,0xC1,0x27,0xDF,0xA6,0x7C,0x7B,0xE3,0x50,0xE8,0xA1,0xCE,0xC3,0xDC, +0xC3,0xCD,0xDF,0x99,0x7F,0xB7,0xF5,0x08,0xEB,0x48,0x79,0x2B,0xD2,0x3A,0xBF,0x75,0xAC,0x2D,0xA3, +0x6D,0xA0,0x3D,0xA1,0xBD,0xEF,0xE8,0x8C,0xA3,0x9D,0x1D,0x5E,0x1D,0x47,0xBE,0xB7,0xFF,0x7E,0xEF, +0x31,0xE3,0x63,0x75,0xC7,0x35,0x8F,0x57,0x9E,0xA0,0x9D,0x28,0x3D,0xF1,0xF9,0xE4,0x82,0x93,0xE3, +0xA7,0x64,0xA7,0x9E,0x9D,0x4E,0x3F,0x3D,0xD4,0x99,0xDC,0x79,0xF7,0x4C,0xFC,0x99,0x6B,0x5D,0x51, +0x5D,0xBD,0x67,0x43,0xCF,0x9E,0x3F,0x17,0x74,0xEE,0x4C,0xB7,0x5F,0xF7,0xC9,0xF3,0xDE,0xE7,0x8F, +0x5D,0xF0,0xBC,0x70,0xF4,0x22,0xF7,0x62,0xDB,0x25,0xB7,0x4B,0xAD,0x3D,0xAE,0x3D,0x47,0x7E,0x70, +0xFD,0xE1,0x48,0xAF,0x5B,0x6F,0xEB,0x65,0xF7,0xCB,0xED,0x57,0x3C,0xAE,0x74,0xF4,0x4D,0xEB,0x3B, +0xD1,0xEF,0xD3,0x7F,0xFA,0x6A,0xC0,0xD5,0x73,0xD7,0xF8,0xD7,0x2E,0x5D,0x9F,0x79,0xBD,0xEF,0xC6, +0xEC,0x1B,0xB7,0x6E,0x26,0xDD,0x1C,0xB8,0x25,0xBA,0xF5,0xF8,0x76,0xF6,0xED,0x17,0x77,0x0A,0xEE, +0x4C,0xDC,0x5D,0x7A,0x8F,0x78,0xAF,0xFC,0xBE,0xDA,0xFD,0xEA,0x07,0xFA,0x0F,0xEA,0x7F,0xB4,0xFE, +0xB1,0x65,0xC0,0x6D,0xE0,0xF8,0x60,0xC0,0x60,0xCF,0xC3,0x59,0x0F,0xEF,0x0E,0x09,0x87,0x9E,0xFE, +0x94,0xFF,0xD3,0x87,0xE1,0xD2,0x47,0xCC,0x47,0xD5,0x23,0x46,0x23,0x8D,0x8F,0x9D,0x1F,0x1F,0x1B, +0x0D,0x1A,0xBD,0xF2,0x64,0xCE,0x93,0xE1,0xA7,0xB2,0xA7,0x13,0xCF,0xCA,0x7E,0x56,0xFF,0x79,0xEB, +0x73,0xAB,0xE7,0xDF,0xFD,0xE2,0xFB,0x4B,0xCF,0x58,0xFC,0xD8,0xF0,0x0B,0xF9,0x8B,0xCF,0xBF,0xAE, +0x79,0xA9,0xF3,0x72,0xEF,0xAB,0xA9,0xAF,0x3A,0xC7,0x23,0xC7,0x1F,0xBC,0xCE,0x79,0x3D,0xF1,0xA6, +0xFC,0xAD,0xCE,0xDB,0x7D,0xEF,0xB8,0xEF,0xBA,0xDF,0xC7,0xBD,0x1F,0x99,0x28,0xFC,0x40,0xFE,0x50, +0xF3,0xD1,0xFA,0x63,0xC7,0xA7,0xD0,0x4F,0xF7,0x3E,0xE7,0x7C,0xFE,0xFC,0x2F,0xF7,0x84,0xF3,0xFB, +0x25,0xD2,0x9F,0x33,0x00,0x00,0x00,0x20,0x63,0x48,0x52,0x4D,0x00,0x00,0x7A,0x25,0x00,0x00,0x80, +0x83,0x00,0x00,0xF9,0xFF,0x00,0x00,0x80,0xE9,0x00,0x00,0x75,0x30,0x00,0x00,0xEA,0x60,0x00,0x00, +0x3A,0x98,0x00,0x00,0x17,0x6F,0x92,0x5F,0xC5,0x46,0x00,0x00,0x03,0x6A,0x49,0x44,0x41,0x54,0x78, +0xDA,0xD4,0x99,0xDB,0x8B,0x4D,0x51,0x1C,0xC7,0x3F,0x73,0x30,0x33,0xB9,0x1B,0x91,0x26,0xE4,0x96, +0x41,0x23,0x64,0xBC,0x10,0x21,0x22,0x49,0xE4,0xC1,0x03,0x25,0xA6,0x49,0xE3,0x6F,0xF0,0xE4,0x4D, +0xA3,0x88,0x72,0x8B,0x79,0x91,0x86,0x22,0x21,0x91,0x68,0x94,0x6B,0x6E,0x33,0xEE,0x23,0x14,0x66, +0x18,0x53,0x43,0x72,0x3B,0xE3,0xFA,0xF5,0x60,0x4D,0x9D,0x8E,0x73,0xF6,0x59,0x6B,0xED,0x7D,0xCE, +0x71,0xBE,0xB5,0xDA,0x9D,0xCE,0xDA,0xBF,0xB5,0xBE,0xEB,0xB7,0x7E,0xD7,0x5D,0x24,0x89,0x42,0x46, +0xCF,0x88,0xE4,0x14,0x03,0x53,0x81,0xF1,0x40,0x15,0x30,0x0E,0x18,0x06,0xF4,0x06,0x3E,0x03,0xED, +0xC0,0x33,0xE0,0x16,0xF0,0x04,0x68,0x02,0xF4,0x3F,0x10,0x98,0x02,0xD4,0x00,0xCB,0x80,0x11,0x0E, +0xEF,0x3D,0x07,0x4E,0x00,0x07,0x80,0x47,0xA1,0x76,0x20,0xC9,0x67,0xCC,0x94,0x74,0x51,0xD1,0xE0, +0xB4,0xA4,0xE9,0x9E,0xFB,0x70,0x26,0x50,0x26,0xE9,0xB0,0xB2,0x83,0x7A,0x49,0xFD,0x5D,0x09,0x14, +0x39,0x18,0xF1,0x2C,0xA3,0xF6,0xC1,0x59,0xB4,0xC9,0x37,0xC0,0x12,0xE0,0xAE,0xED,0x0B,0x31,0xCB, +0x79,0x6B,0x81,0xCB,0x59,0xDE,0x3C,0x40,0x39,0x70,0x07,0x58,0x1E,0xA5,0x0D,0x54,0x2B,0x3F,0x58, +0x15,0xC5,0x15,0x5A,0x09,0x1C,0xCD,0xA3,0x9B,0x5F,0x08,0x9C,0x0F,0x9A,0x10,0x44,0x60,0x0C,0x70, +0x0D,0x18,0x9A,0x47,0x02,0x6D,0xC6,0xF6,0x5E,0xF9,0xD8,0x40,0x7D,0x9E,0x37,0x0F,0x30,0x1C,0xD8, +0xE3,0xA3,0x81,0x1A,0x60,0x9F,0xC7,0x82,0x5D,0xE6,0x50,0x9A,0x4C,0x90,0xEA,0x6D,0x22,0xEE,0x67, +0xA0,0x1A,0x98,0x06,0xFC,0x06,0xFA,0x38,0xCA,0x5D,0x03,0x1C,0xB2,0x35,0xE2,0x52,0x49,0x4F,0x3D, +0x8C,0xEE,0x8A,0xA4,0x05,0x92,0x7A,0x49,0x2A,0x49,0x21,0xB7,0xD8,0x3C,0xE7,0x48,0x3A,0x22,0xE9, +0xAB,0x83,0xEC,0xBB,0x2E,0x81,0x6C,0xBD,0xE3,0xC6,0x5B,0x25,0xCD,0xF7,0x88,0xA2,0xF3,0x24,0x7D, +0x72,0x58,0x67,0xB5,0x2D,0x81,0x46,0x07,0xA1,0xED,0x92,0x26,0xF9,0xA6,0x01,0x46,0x1B,0x3F,0x2D, +0xD7,0x6A,0xB4,0x21,0x30,0x5A,0x52,0xDC,0x52,0x60,0xA7,0xA4,0x09,0x21,0x36,0xEF,0xAA,0xF1,0xB8, +0xA4,0x8A,0xE4,0xF7,0x63,0x49,0x6E,0x73,0x05,0x50,0x6A,0x61,0x54,0x1F,0x81,0xB9,0x40,0x4B,0x04, +0x9E,0xA6,0x1E,0x38,0x65,0x31,0xAF,0x14,0x58,0x14,0xE4,0x46,0x87,0x03,0x63,0x2D,0x17,0xDD,0x05, +0x3C,0x88,0xD0,0x5D,0xD6,0x59,0xCE,0x9B,0x1C,0x44,0x60,0x06,0x50,0x69,0x21,0xE4,0x3D,0xB0,0x3D, +0x62,0x7F,0x7F,0x09,0xB8,0x62,0x59,0x7F,0xA4,0x25,0x30,0xD1,0x5C,0xA3,0x4C,0xD8,0x0B,0x74,0x64, +0x21,0x68,0xD9,0x68,0xB4,0xC2,0x54,0x7A,0x29,0x09,0x94,0x03,0x43,0x32,0x08,0x88,0x03,0xFB,0xB3, +0x14,0x75,0x6D,0x34,0x50,0x02,0xF4,0x4D,0x47,0xA0,0x9F,0x99,0x10,0x84,0x5F,0xC0,0x97,0x2C,0x11, +0x68,0xB5,0x98,0xD3,0x03,0xE8,0x95,0x8E,0xC0,0x77,0x13,0xE6,0x03,0xB3,0x6F,0x43,0x22,0x1B,0xB0, +0xAD,0xAC,0x62,0xE9,0x7E,0xBC,0x05,0xDE,0x65,0x78,0xF9,0x37,0xF0,0xC3,0x63,0x73,0x03,0xCD,0x08, +0xC2,0x08,0x1F,0xA2,0x89,0x04,0x9E,0x05,0xA5,0xAD,0x21,0xD1,0x60,0x2A,0xAD,0xB2,0x0C,0x25,0x2B, +0x16,0x57,0xF8,0x5B,0x3A,0x02,0xD7,0x81,0x7B,0x19,0x04,0xF4,0x75,0x6C,0x9F,0x74,0x63,0x14,0x30, +0x1A,0x38,0x17,0x40,0x62,0xB2,0x25,0x81,0xAE,0x74,0x04,0xDE,0x98,0x91,0xC9,0x88,0x56,0x78,0x10, +0xF8,0x69,0x9E,0xD3,0x81,0x0B,0xC6,0x61,0x24,0x62,0xB6,0xA5,0x06,0xF4,0x8F,0xAD,0x24,0xE5,0x16, +0x55,0x16,0x39,0x49,0x9B,0xA4,0x41,0x8E,0xF9,0xCE,0xBD,0x24,0x19,0xF7,0x93,0x5A,0x28,0x27,0x2D, +0xF3,0xA1,0x17,0x92,0x06,0x04,0x25,0x73,0x3D,0x25,0x3D,0xB4,0x10,0xB4,0xC7,0x91,0x40,0x2A,0x99, +0xCD,0xE6,0xBF,0xE5,0x0E,0xD9,0xEF,0xA6,0xA0,0x64,0xAE,0x5B,0xD5,0x0D,0x16,0xAA,0xDC,0x00,0x6C, +0x74,0xB8,0x42,0xB1,0x34,0x69,0xC1,0x7D,0xC7,0xB4,0xE4,0xB6,0x4D,0x45,0x36,0x52,0xD2,0x07,0x8B, +0xD3,0x78,0x6B,0x3A,0x75,0x36,0x1A,0x78,0x1C,0x41,0x9B,0xE5,0x71,0x2A,0xD9,0xA9,0x4E,0xE6,0x15, +0xB0,0xDB,0xE2,0x34,0x0E,0x9A,0xC4,0x2E,0x57,0x68,0x70,0xE9,0x4A,0x6C,0x01,0x5E,0x67,0x10,0x78, +0x35,0x87,0x9B,0xEF,0x30,0x29,0xBC,0x35,0x81,0x0F,0x40,0x6D,0x80,0xC0,0x9D,0xC0,0xF1,0x1C,0x12, +0xD8,0x01,0x74,0xFA,0xB4,0x16,0x37,0xA7,0xB8,0x8B,0x5B,0x3D,0xCA,0xC6,0x96,0x10,0x77,0xBF,0x2E, +0x6C,0x7B,0xFD,0x40,0x42,0xE1,0xBD,0xCD,0xB3,0xEE,0xF5,0x25,0xD0,0x6C,0x5C,0x7B,0x5A,0xD9,0x36, +0xDD,0xE9,0x5A,0xD3,0xA1,0x9B,0x0D,0x6C,0xCA,0x71,0x67,0xEE,0x58,0x42,0x14,0x77,0xEE,0x8D,0x46, +0x89,0x16,0x53,0x4D,0xB9,0xE2,0x97,0x69,0xF0,0x36,0x86,0xFD,0x3E,0x90,0x2F,0xF4,0x00,0xCE,0x02, +0x8B,0x0B,0x95,0x00,0xFC,0xFD,0x02,0x7A,0x06,0x58,0x5A,0xA8,0x04,0xBA,0x71,0x0A,0x58,0x97,0x2F, +0x02,0x37,0x12,0x2A,0xBA,0x30,0xA8,0x74,0x8D,0x03,0x51,0x8D,0x98,0xE9,0x4E,0xD7,0x48,0x7A,0xE9, +0xE9,0x52,0x8F,0x85,0xFD,0x4A,0x19,0x15,0xCA,0x4D,0xF5,0x15,0xB7,0x98,0x5B,0x64,0x6E,0x49,0x31, +0x70,0x33,0x55,0xEE,0x95,0x0F,0x02,0x91,0x22,0x46,0x81,0xE3,0xCF,0x00,0xD2,0xF0,0xF4,0x75,0x05, +0xC1,0xEC,0xA0,0x00,0x00,0x00,0x00,0x49,0x45,0x4E,0x44,0xAE,0x42,0x60,0x82}; diff --git a/archive/blr1/src/main.cpp b/archive/blr1/src/main.cpp new file mode 100644 index 0000000..d0ca2ed --- /dev/null +++ b/archive/blr1/src/main.cpp @@ -0,0 +1,510 @@ +//Chrisoft Bullet Lab Remix HGE
+//Main Code
+//"Copyleft" Chrisoft 2013
+//#define Debug
+#include "hge.h"
+#include "hgefont.h"
+#include "hgegui.h"
+#include <cmath>
+#include <ctime>
+#include <cstdlib>
+#include <cstdio>
+#include "menuitem.h"
+#include "global.h"
+#include "towernbullet.h"
+#include "levels.h"
+#include "scorec.h"
+#include "menus.h"
+void firststartup()
+{
+ /*if (MessageBoxA(NULL,"It seems that you are running BLR for the First time!\nLet's do some \
+basic settings first!\n\nEnable Low FPS Mode?","First Start Up",0x00000024)==6)
+ fpslvl=1;
+ else*/
+ fpslvl=0;
+ /*if (MessageBoxA(NULL,"Enable Fullscreen?","First Start Up",0x00000024)==6)
+ tfs=1;
+ else*/
+ tfs=0;
+ diffkey=false;
+ plrspd=3;plrslospd=3;clrbns=0;
+ hge->System_Log("Finishing first start up configuraion...");
+ Options_Writeback();
+ Score_Initailize();
+}
+void Player_Clear()
+{
+ if (LOWFPS)
+ clrrange+=13.6;
+ else
+ clrrange+=0.8;
+ for (int i=1;i<=bulcnt;++i)
+ {
+ double dis=GetDist(bullet[i].bulletpos,playerpos);
+ if (dis<=clrrange&&bullet[i].exist)
+ {
+ CreateBullet255(bullet[i].bulletpos.x,bullet[i].bulletpos.y,10);
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ }
+}
+void ProcessPlayer()
+{
+ playerspr->RenderEx(playerpos.x+8.4,playerpos.y+8.4,playerrot,0.7,0);
+ if (DisablePlayer)return;
+ if (!LOWFPS)
+ playerrot+=0.00174533;
+ else
+ playerrot+=0.00174533*17;
+ double realspd;
+ if (hge->Input_GetKeyState(HGEK_SHIFT))
+ if (LOWFPS)
+ realspd=playerslospeed*17;
+ else
+ realspd=playerslospeed;
+ else
+ if (LOWFPS)
+ realspd=playerspeed*17;
+ else
+ realspd=playerspeed;
+ if (hge->Input_GetKeyState(HGEK_LEFT))
+ {
+ if (playerpos.x>10)
+ playerpos.x-=realspd;
+ }
+ if (hge->Input_GetKeyState(HGEK_RIGHT))
+ {
+ if (playerpos.x<770)
+ playerpos.x+=realspd;
+ }
+ if (hge->Input_GetKeyState(HGEK_UP))
+ {
+ if (playerpos.y>10)
+ playerpos.y-=realspd;
+ }
+ if (hge->Input_GetKeyState(HGEK_DOWN))
+ {
+ if (playerpos.y<570)
+ playerpos.y+=realspd;
+ }
+ if (hge->Input_GetKeyState(HGEK_Z)&&clrrange==0&&clrtime+clrbns&&!diffkey)
+ {
+ Player_Clear();--clrtime;++clrusg;
+ }
+ if (hge->Input_GetKeyState(HGEK_X)&&clrrange==0&&clrtime+clrbns&&diffkey)
+ {
+ Player_Clear();--clrtime;++clrusg;
+ }
+ //Player_Attack();
+ if (clrrange!=0)Player_Clear();
+ if (clrrange>=300)clrrange=0;
+}
+void RefreshScore()
+{
+ if (DisablePlayer)return;
+ int multp=1;
+ if (mode==2)multp=5;
+ if (LOWFPS)
+ score+=multp*16;
+ else
+ score+=multp;
+ score+=100*shots;
+ score-=scminus;
+ score+=2000*dsmc;
+ ++frms;
+ averfps=(averfps*(frms-1)+hge->Timer_GetFPS())/(double)frms;
+}
+void CallLevels()
+{
+ //Use this to call level procedures.
+ //Don't use this to call the first level!
+ if (level<6)clrtime=0;
+ if ((mode==4||mode<=2)&&coll!=0){DeathGUI_Init();return;}
+ if (!IfCallLevel) return;
+ if (level==7&&part==0&&mode==4)//Easy
+ {
+ CompleteGUI_Init();
+ return;
+ }
+ if (level==8&&part==0&&mode==4)//Easy
+ {
+ CompleteGUI_Init();
+ return;
+ }
+ if (level==8&&part==12&&(mode==2||mode==3))//Extreme or FPM
+ {
+ CompleteGUI_Init();
+ return;
+ }
+ if (level==1&&part==1)Level1Part1();
+ if (level==1&&part==2)Level1Part2();
+ if (level==1&&part==3)Level1Part3();
+ if (level==1&&part==4)Level1Part4();
+ if (level==2&&part==0)Level2Part0();
+ if (level==2&&part==1)Level2Part1();
+ if (level==2&&part==2)Level2Part2();
+ if (level==2&&part==3)Level2Part3();
+ if (level==3&&part==0)Level3Part0();
+ if (level==3&&part==1)Level3Part1();
+ if (level==3&&part==2)Level3Part2();
+ if (level==3&&part==3)Level3Part3();
+ if (level==3&&part==4)Level3Part4();
+ if (level==3&&part==5)Level3Part5();
+ if (level==3&&part==6)Level3Part6();
+ if (level==3&&part==7)Level3Part7();
+ if (level==4&&part==0)Level4Part0();
+ if (level==4&&part==1)Level4Part1();
+ if (level==4&&part==2)Level4Part2();
+ if (level==4&&part==3)Level4Part3();
+ if (level==4&&part==4)Level4Part4();
+ if (level==4&&part==5)Level4Part5();
+ if (level==4&&part==6)Level4Part6();
+ if (level==5&&part==0)Level5Part0();
+ if (level==5&&part==1)Level5Part1();
+ if (level==5&&part==2)Level5Part2();
+ if (level==5&&part==3)Level5Part3();
+ if (level==5&&part==4)Level5Part4();
+ if (level==6&&part==0)Level6Part0();
+ if (level==6&&part==1)Level6Part1();
+ if (level==6&&part==2)Level6Part2();
+ if (level==6&&part==3)Level6Part3();
+ if (level==6&&part==4)Level6Part4();
+ if (level==6&&part==5)Level6Part5();
+ if (level==6&&part==6)Level6Part6();
+ if (level==6&&part==7)Level6Part7();
+ if (level==6&&part==8)Level6Part8();
+ if (level==6&&part==9)Level6Part9();
+ if (level==7&&part==0)Level7Part0();
+ if (level==7&&part==1)Level7Part1();
+ if (level==7&&part==2)Level7Part2();
+ if (level==7&&part==3)Level7Part3();
+ if (level==7&&part==4)Level7Part4();
+ if (level==7&&part==5)Level7Part5();
+ if (level==7&&part==6)Level7Part6();
+ if (level==7&&part==7)Level7Part7();
+ if (level==7&&part==8)Level7Part8();
+ if (level==7&&part==9)Level7Part9();
+ if (level==7&&part==10)Level7Part10();
+ if (level==7&&part==11)Level7Part11();
+ if (level==7&&part==12)Level7Part12();
+ if (level==8&&part==0)Level8Part0();
+ if (level==8&&part==1)Level8Part1();
+ if (level==8&&part==2)Level8Part2();
+ if (level==8&&part==3)Level8Part3();
+ if (level==8&&part==4)Level8Part4();
+ if (level==8&&part==5)Level8Part5();
+ if (level==8&&part==6)Level8Part6();
+ if (level==8&&part==7)Level8Part7();
+ if (level==8&&part==8)Level8Part8();
+ if (level==8&&part==9)Level8Part9();
+ if (level==8&&part==10)Level8Part10();
+ if (level==8&&part==11)Level8Part11();
+}
+void AboutScene()
+{
+ if (LOWFPS)scroll+=0.51;else scroll+=0.03;
+ Credits->Render(200,600-scroll);
+ CreditsRail->Render(200,0);
+ if(hge->Input_GetKeyState(HGEK_Z)||scroll>1624)
+ {
+ Current_Position=0;
+ gui->SetFocus(1);
+ gui->Enter();
+ }
+}
+bool FrameFunc()
+{
+ float dt=hge->Timer_GetDelta();
+ static float t=0.0f;
+ float tx,ty;
+ int id;
+ static int lastid=0;
+ // If ESCAPE was pressed, tell the GUI to finish
+ if (hge->Input_GetKeyState(HGEK_ESCAPE)&&Current_Position==0) { lastid=5; gui->Leave(); }
+ if (Current_Position==1&&hge->Input_GetKeyState(HGEK_ESCAPE))PauseGUI_Init();
+ // We update the GUI and take an action if
+ // one of the menu items was selected
+ if (Current_Position==0)
+ {
+ id=gui->Update(dt);
+ if(id == -1)
+ {
+ switch(lastid)
+ {
+ case 1:Current_Position=3; StartGUI_Init();gui->Leave();break;
+ case 2:gui->Leave();HighScoreGUI_Init();break;
+ case 3:gui->Leave();OptionsGUI_Init();break;
+ case 4:
+ Credits=new hgeSprite(TexCredits,0,0,400,1024);
+ CreditsRail=new hgeSprite(TexCredits,400,0,400,1024);
+ scroll=0;
+ Current_Position=4;
+ AboutScene();
+ lastid=0;
+ break;
+ case 5: return true;
+ }
+ }
+ else if(id) { lastid=id; gui->Leave(); }
+ }
+ if (Current_Position==3)StartGUI_FrameFnk();
+ if (Current_Position==5)DeathGUI_FrameFnk();
+ if (Current_Position==6)CompleteGUI_FrameFnk();
+ if (Current_Position==7)NewHighScoreGUI_FrameFnk();
+ if (Current_Position==8)HighScoreGUI_FrameFnk();
+ if (Current_Position==9)HSViewGUI_FrameFnk();
+ if (Current_Position==10)HSDetGUI_FrameFnk();
+ if (Current_Position==11)PauseGUI_FrameFnk();
+ if (Current_Position==12)BkTTitleGUI_FrameFnk();
+ if (Current_Position==13)OptionsGUI_FrameFnk();
+ if (Current_Position==14)PlayerProfGUI_FrameFnk();
+ // Here we update our background animation
+ t+=dt;
+ tx=50*cosf(t/60);
+ ty=50*sinf(t/60);
+ quad.v[0].tx=tx; quad.v[0].ty=ty;
+ quad.v[1].tx=tx+800/64; quad.v[1].ty=ty;
+ quad.v[2].tx=tx+800/64; quad.v[2].ty=ty+600/64;
+ quad.v[3].tx=tx; quad.v[3].ty=ty+600/64;
+ return false;
+}
+bool RenderFunc()
+{
+ // Render graphics
+ hge->Gfx_BeginScene();
+ hge->Gfx_RenderQuad(&quad);
+ if (Current_Position==0||Current_Position==3||Current_Position==8||
+ Current_Position==9||Current_Position==10||Current_Position==13||Current_Position==14)
+ {
+ if (Current_Position==0)
+ gui->Render();
+ titlespr->Render(160,0);
+ }
+ if (Current_Position==3)
+ StartGUI->Render();
+ if (Current_Position==1||Current_Position==2||Current_Position==5||Current_Position==11||Current_Position==12)
+ {
+ //If we are at the main scene or tip scene(which towers and bullets should still appear..)
+ //Render towers, bullets and player.
+ shots=0;
+ dsmc=0;
+ scminus=0;
+ ProcessTower1();
+ ProcessTower2();
+ ProcessTower3();
+ ProcessTower4();
+ ProcessTower5();
+ ProcessTower6();
+ ProcessTower7();
+ ProcessBullet1();
+ ProcessBullet2();
+ //No ProcessBullet3() needed
+ ProcessBullet4();
+ ProcessBullet5();
+ ProcessBullet6();
+ ProcessBullet7();
+ ProcessBullet255();
+ ProcessPlayer();
+ SCEffect_Process();
+ RefreshScore();
+ if (!DisablePlayer)
+ --frameleft;//If we are at the tip scene, disable the player movement.
+ if (!LOWFPS)
+ {
+ if (playerspeed<playerfulspd)playerspeed+=playerfulspd/400;
+ if (playerslospeed<playerfulslospd)playerslospeed+=playerfulslospd/400;
+ }
+ else
+ {
+ if (playerspeed<playerfulspd)playerspeed+=playerfulspd/25;
+ if (playerslospeed<playerfulslospd)playerslospeed+=playerfulslospd/25;
+ }
+ }
+ if (frameleft == 0&&Current_Position==1)
+ {
+ IfCallLevel=true;
+ ++part;
+ IfShowTip=true;
+ if (level==1&&part==5)++level,part=0;
+ if (level==2&&part==4)++level,part=0;
+ if (level==3&&part==8)++level,part=0;
+ if (level==4&&part==7)++level,part=0;
+ if (level==5&&part==5)++level,part=0;
+ if (level==6&&part==10)++level,part=0;
+ if (level==7&&part==13)++level,part=0;
+ }
+ if (Current_Position==1)
+ {
+ CallLevels();
+ }
+ if (shots)hge->Effect_Play(snd);
+ if (Current_Position==2)
+ {
+ ShowTip(lasttip);
+ //if (Complete)
+ // TipFont->printf(200,200,HGETEXT_LEFT,"Score");
+ }
+ if (Current_Position==4)AboutScene();
+ if (Current_Position==5)DeathGUI->Render();
+ if (Current_Position==6)CompleteGUI->Render();
+ if (Current_Position==7)NewHighScoreGUI_Render();
+ if (Current_Position==8)HighScoreGUI->Render();
+ if (Current_Position==9)HSViewGUI->Render();
+ if (Current_Position==10)HSDetailGUI->Render();
+ if (Current_Position==11)PauseGUI->Render();
+ if (Current_Position==12)BkTTitleGUI->Render();
+ if (Current_Position==13)OptionsGUI->Render();
+ if (Current_Position==14)PlayerProfGUI->Render();
+ fnt->SetColor(0xFFFFFFFF);
+ fnt->printf(680, 575, HGETEXT_LEFT, "FPS: %d", hge->Timer_GetFPS());
+ if (Current_Position==1||Current_Position==2)
+ {
+ fnt->printf(670,555, HGETEXT_LEFT, "AF: %.2f", averfps);
+ fnt->printf(5, 0, HGETEXT_LEFT, "Frames to go: %d",frameleft);
+ fnt->printf(5, 25, HGETEXT_LEFT, "Score: %lld",score);
+ fnt->printf(5, 50, HGETEXT_LEFT, "Level %d Part %d",level,part);
+ if (mode==3)
+ fnt->printf(5, 75, HGETEXT_LEFT, "Collisions: %d",coll);
+ else
+ fnt->printf(5, 75, HGETEXT_LEFT, "Restarts: %d",restarts);
+ fnt->printf(5, 100, HGETEXT_LEFT, "Semi-Collisions: %d",semicoll);
+ fnt->printf(5, 125, HGETEXT_LEFT, "Clear Range Left: %d",clrtime+clrbns);
+ }
+ hge->Gfx_EndScene();
+ return false;
+}
+int main()
+{
+ srand(time(NULL));
+ hge = hgeCreate(HGE_VERSION);
+ hge->System_SetState(HGE_LOGFILE, "BLRLOG.txt");
+ hge->System_Log("Bullet Lab Remix Log File");
+ hge->System_Log("Folder Decompressed created successfully.");
+ /*
+ Resourece Files list
+ bg.lz->bg.png
+ blnsns.lz->blnsns.png
+ charmap.lz->charmap.fnt
+ ss1.lz->ss1.png
+ ss2.lz->ss2.png
+ title.lz->title.png
+ credits.lz->credits.png
+ tap.lz->tap.wav
+ */
+ hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
+ hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
+ hge->System_SetState(HGE_TITLE, "Bullet Lab Remix");
+ hge->System_SetState(HGE_WINDOWED, true);
+ hge->System_SetState(HGE_SCREENWIDTH, 800);
+ hge->System_SetState(HGE_SCREENHEIGHT, 600);
+ hge->System_SetState(HGE_SCREENBPP, 32);
+ hge->System_SetState(HGE_SHOWSPLASH, false);
+ hge->System_SetState(HGE_FPS,0);
+ if((access("blr.cfg",0))==-1)
+ {
+ hge->System_Log("Config file not found. Calling first startup.");
+ firststartup();
+ }
+ hge->System_Log("Loading config file");
+ freopen("blr.cfg","r",stdin);
+ char tch=getchar();
+ if (tch!=';'){}
+ tch=getchar();
+ if (tch!='C'){}
+ tch=getchar();
+ if (tch!='B'){}
+ tch=getchar();
+ if (tch!='L'){}
+ fpslvl=0;
+ tch=getchar();//LOWFPS
+ if (tch==1)
+ {
+ LOWFPS=true;
+ TenSeconds=600;
+ TwentySeconds=1200;
+ ThirtySeconds=1800;
+ AMinute=3600;
+ hge->System_SetState(HGE_FPS,61);
+ fpslvl=1;
+ }
+ tch=getchar();//FULLSCRREEN
+ tfs=false;
+ if (tch==1)
+ hge->System_SetState(HGE_WINDOWED, false),tfs=true;
+ tch=getchar();//LockFPS
+ if (tch==1&&!LOWFPS)
+ {
+ hge->System_SetState(HGE_FPS,1000);
+ fpslvl=2;
+ }
+ tch=getchar();//Key binding
+ if (tch==1)diffkey=true;
+ plrspd=tch=getchar();
+ playerfulspd=(tch)*0.05f;
+ playerspeed=playerfulspd;
+ plrslospd=tch=getchar();
+ playerfulslospd=(tch)*0.0125f;
+ playerslospeed=playerfulslospd;
+ tch=getchar();
+ clrbns=tch;
+ fclose(stdin);
+ if (AP_Update(plrspd,plrslospd,clrbns)>10000)Error("Invalid configuration!\nDelete blr.cfg and run the game again!");
+ hge->System_Log("Loading Score file");
+ Score_Init();
+#ifdef Debug
+ playerspeed=playerfulspd=0.2;
+ playerslospeed=playerfulslospd=0.05;
+#endif
+ Current_Position=0;//We are at the main menu at first
+ if(hge->System_Initiate())
+ {
+ quad.tex=hge->Texture_Load("./Resources/bg.png");
+ SprSheet1=hge->Texture_Load("./Resources/ss1.png");
+ SprSheet2=hge->Texture_Load("./Resources/ss2.png");
+ TexTitle=hge->Texture_Load("./Resources/title.png");
+ TexCredits=hge->Texture_Load("./Resources/credits.png");
+ snd=hge->Effect_Load("./Resources/tap.ogg");
+ titlespr=new hgeSprite(TexTitle,0,0,640,320);
+ playerspr=new hgeSprite(SprSheet1,47,46,24,24);
+ playerspr->SetHotSpot(12,12);//Set player anchor
+ playerspr->SetColor(0xC0FFFFFF);
+ if(!quad.tex||!SprSheet1||!SprSheet2||!TexTitle||!TexCredits)
+ {
+ Error("Error Loading Resources!",true);
+ }
+ quad.blend=BLEND_ALPHABLEND | BLEND_COLORMUL | BLEND_NOZWRITE;
+ for(int i=0;i<4;i++)
+ {
+ quad.v[i].z=0.5f;
+ quad.v[i].col=0xFFFFFFFF;
+ }
+ quad.v[0].x=0; quad.v[0].y=0;
+ quad.v[1].x=800; quad.v[1].y=0;
+ quad.v[2].x=800; quad.v[2].y=600;
+ quad.v[3].x=0; quad.v[3].y=600;
+ fnt=new hgeFont("./Resources/charmap.fnt");
+ TipFont=new hgeFont("./Resources/charmap.fnt");
+ spr=new hgeSprite(SprSheet1,24,46,24,24);
+ gui=new hgeGUI();
+ gui->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Start"));
+ gui->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,"Highscores && Records"));
+ gui->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,"Options"));
+ gui->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,"About"));
+ gui->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Exit"));
+ gui->SetNavMode(HGEGUI_UPDOWN | HGEGUI_CYCLED);
+ gui->SetCursor(spr);
+ gui->SetFocus(1);
+ gui->Enter();
+ if (LOWFPS)
+ hge->System_Log("Low FPS Mode Enabled.\n");
+ hge->System_Start();
+ }
+ // Clean up and shutdown
+ hge->System_Shutdown();
+ hge->Release();
+ return 0;
+}
diff --git a/archive/blr1/src/menuitem.cpp b/archive/blr1/src/menuitem.cpp new file mode 100644 index 0000000..353b6b7 --- /dev/null +++ b/archive/blr1/src/menuitem.cpp @@ -0,0 +1,201 @@ +/*
+** Haaf's Game Engine 1.7
+** Copyright (C) 2003-2007, Relish Games
+** hge.relishgames.com
+**
+** Tutorial 06 - Creating menus
+*/
+
+// In menuitem.cpp/h we define the
+// behaviour of our custom GUI control
+
+#include "menuitem.h"
+#define UnfocColor 0xFFAAAAAA
+#define FocColor 0xFFFFFFFF
+// This is a GUI control constructor,
+// we should initialize all the variables here
+hgeGUIMenuItem::hgeGUIMenuItem(int _id, hgeFont *_fnt, HEFFECT _snd, float _x, float _y, float _delay, char *_title)
+{
+ float w;
+
+ id=_id;
+ fnt=_fnt;
+ snd=_snd;
+ delay=_delay;
+ title=_title;
+
+ color.SetHWColor(UnfocColor);
+ shadow.SetHWColor(0x30000000);
+ offset=0.0f;
+ timer=-1.0f;
+ timer2=-1.0f;
+
+ bStatic=false;
+ bVisible=true;
+ bEnabled=true;
+
+ w=fnt->GetStringWidth(title);
+ rect.Set(_x-w/2, _y, _x+w/2, _y+fnt->GetHeight());
+}
+
+// Reposition the item
+void hgeGUIMenuItem::RePos(float x,float y)
+{
+ float w=fnt->GetStringWidth(title);
+ rect.Set(x-w/2, y, x+w/2, y+fnt->GetHeight());
+}
+
+// This method is called when the control should be rendered
+void hgeGUIMenuItem::Render()
+{
+ fnt->SetColor(shadow.GetHWColor());
+ fnt->Render(rect.x1+offset+3, rect.y1+3, HGETEXT_LEFT, title);
+ fnt->SetColor(color.GetHWColor());
+ fnt->Render(rect.x1-offset, rect.y1-offset, HGETEXT_LEFT, title);
+}
+
+// This method is called each frame,
+// we should update the animation here
+void hgeGUIMenuItem::Update(float dt)
+{
+ if(timer2 != -1.0f)
+ {
+ timer2+=dt;
+ if(timer2 >= delay+0.1f)
+ {
+ color=scolor2+dcolor2;
+ shadow=sshadow+dshadow;
+ offset=0.0f;
+ timer2=-1.0f;
+ }
+ else
+ {
+ if(timer2 < delay) { color=scolor2; shadow=sshadow; }
+ else { color=scolor2+dcolor2*(timer2-delay)*10; shadow=sshadow+dshadow*(timer2-delay)*10; }
+ }
+ }
+ else if(timer != -1.0f)
+ {
+ timer+=dt;
+ if(timer >= 0.2f)
+ {
+ color=scolor+dcolor;
+ offset=soffset+doffset;
+ timer=-1.0f;
+ }
+ else
+ {
+ color=scolor+dcolor*timer*5;
+ offset=soffset+doffset*timer*5;
+ }
+ }
+}
+
+// This method is called when the GUI
+// is about to appear on the screen
+void hgeGUIMenuItem::Enter()
+{
+ hgeColor tcolor2;
+
+ scolor2.SetHWColor(UnfocColor&0x00FFFFFF);
+ tcolor2.SetHWColor(UnfocColor);
+ dcolor2=tcolor2-scolor2;
+
+ sshadow.SetHWColor(0x00000000);
+ tcolor2.SetHWColor(0x30000000);
+ dshadow=tcolor2-sshadow;
+
+ timer2=0.0f;
+}
+
+// This method is called when the GUI
+// is about to disappear from the screen
+void hgeGUIMenuItem::Leave()
+{
+ hgeColor tcolor2;
+
+ scolor2.SetHWColor(UnfocColor);
+ tcolor2.SetHWColor(UnfocColor&0x00FFFFFF);
+ dcolor2=tcolor2-scolor2;
+
+ sshadow.SetHWColor(0x30000000);
+ tcolor2.SetHWColor(0x00000000);
+ dshadow=tcolor2-sshadow;
+
+ timer2=0.0f;
+}
+
+// This method is called to test whether the control
+// have finished it's Enter/Leave animation
+bool hgeGUIMenuItem::IsDone()
+{
+ if(timer2==-1.0f) return true;
+ else return false;
+}
+
+// This method is called when the control
+// receives or loses keyboard input focus
+void hgeGUIMenuItem::Focus(bool bFocused)
+{
+ hgeColor tcolor;
+
+ if(bFocused)
+ {
+ hge->Effect_Play(snd);
+ scolor.SetHWColor(UnfocColor);
+ tcolor.SetHWColor(FocColor);
+ soffset=0;
+ doffset=4;
+ }
+ else
+ {
+ scolor.SetHWColor(FocColor);
+ tcolor.SetHWColor(UnfocColor);
+ soffset=4;
+ doffset=-4;
+ }
+
+ dcolor=tcolor-scolor;
+ timer=0.0f;
+}
+
+// This method is called to notify the control
+// that the mouse cursor has entered or left it's area
+void hgeGUIMenuItem::MouseOver(bool bOver)
+{
+ if(bOver) gui->SetFocus(id);
+}
+
+// This method is called to notify the control
+// that the left mouse button state has changed.
+// If it returns true - the caller will receive
+// the control's ID
+bool hgeGUIMenuItem::MouseLButton(bool bDown)
+{
+ if(!bDown)
+ {
+ offset=4;
+ return true;
+ }
+ else
+ {
+ hge->Effect_Play(snd);
+ offset=0;
+ return false;
+ }
+}
+
+// This method is called to notify the
+// control that a key has been clicked.
+// If it returns true - the caller will
+// receive the control's ID
+bool hgeGUIMenuItem::KeyClick(int key, int chr)
+{
+ if(key==HGEK_ENTER || key==HGEK_SPACE || key==HGEK_Z)
+ {
+ MouseLButton(true);
+ return MouseLButton(false);
+ }
+
+ return false;
+}
diff --git a/archive/blr1/src/menuitem.h b/archive/blr1/src/menuitem.h new file mode 100644 index 0000000..5788ed9 --- /dev/null +++ b/archive/blr1/src/menuitem.h @@ -0,0 +1,46 @@ +/*
+** Haaf's Game Engine 1.7
+** Copyright (C) 2003-2007, Relish Games
+** hge.relishgames.com
+**
+** Tutorial 06 - Creating menus
+*/
+
+// In menuitem.cpp/h we define the
+// behaviour of our custom GUI control
+
+#include "hge.h"
+#include "hgegui.h"
+#include "hgefont.h"
+#include "hgecolor.h"
+
+
+class hgeGUIMenuItem : public hgeGUIObject
+{
+public:
+ hgeGUIMenuItem(int id, hgeFont *fnt, HEFFECT snd, float x, float y, float delay, char *title);
+
+ virtual void Render();
+ virtual void Update(float dt);
+
+ virtual void Enter();
+ virtual void Leave();
+ virtual bool IsDone();
+ virtual void Focus(bool bFocused);
+ virtual void MouseOver(bool bOver);
+
+ virtual bool MouseLButton(bool bDown);
+ virtual bool KeyClick(int key, int chr);
+ virtual void RePos(float x,float y);
+ char *title;
+
+private:
+ hgeFont *fnt;
+ HEFFECT snd;
+ float delay;
+
+ hgeColor scolor, dcolor, scolor2, dcolor2, sshadow, dshadow;
+ hgeColor color, shadow;
+ float soffset, doffset, offset;
+ float timer, timer2;
+};
diff --git a/archive/blr1/src/menus.h b/archive/blr1/src/menus.h new file mode 100644 index 0000000..cffcee7 --- /dev/null +++ b/archive/blr1/src/menus.h @@ -0,0 +1,742 @@ +//Chrisoft Bullet Lab Remix HGE
+//Menu Implementations
+//"Copyleft" Chrisoft 2013
+hgeGUI *StartGUI,*DeathGUI,*CompleteGUI,*HighScoreGUI;
+hgeGUI *HSViewGUI,*HSDetailGUI,*PauseGUI,*BkTTitleGUI;
+hgeGUI *OptionsGUI,*PlayerProfGUI;
+char ds1[255],ds2[255],ds3[255],ds4[255];
+char hs1[255],hs2[255],hs3[255],hs4[255],hs5[255],hs6[255];
+char HSVstr[7][255];
+char HSDetstr[10][255];
+char opt[10][255];
+bool toogleundl;
+int view,detv;
+int lastkeypressed;
+void HSViewGUI_Init();
+void HighScoreGUI_Init();
+void PauseGUI_Init();
+void StartGUI_Init()
+{
+ StartGUI=new hgeGUI();
+ StartGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Easy"));
+ StartGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,"Normal"));
+ StartGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,"Extreme"));
+ StartGUI->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,"Free Play Mode"));
+ StartGUI->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Back"));
+ StartGUI->SetCursor(spr);
+ StartGUI->SetNavMode(HGEGUI_UPDOWN);
+ StartGUI->SetFocus(1);
+ StartGUI->Enter();
+}
+void StartGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=StartGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 1:
+ playerpos.x=400,playerpos.y=400,playerrot=0;
+ frameleft=TenSeconds;
+ level=1,part=1;frms=0,averfps=0.0;restarts=0;bsscale=0.75;
+ towcnt=bulcnt=0;
+ mode=4;
+ score=0;
+ coll=semicoll=clrusg=0;
+ memset(tower,0,sizeof(tower));
+ memset(bullet,0,sizeof(bullet));
+ Complete=false;
+ Refliction=false;
+ Level1Part1();
+ IfCallLevel=true;
+ break;
+ case 2:
+ playerpos.x=400,playerpos.y=400,playerrot=0;
+ frameleft=TenSeconds;
+ level=1,part=1;frms=0,averfps=0.0;restarts=0;bsscale=1;
+ towcnt=bulcnt=0;
+ mode=1;
+ score=0;
+ coll=semicoll=clrusg=0;
+ memset(tower,0,sizeof(tower));
+ memset(bullet,0,sizeof(bullet));
+ Complete=false;
+ Refliction=false;
+ Level1Part1();
+ IfCallLevel=true;
+ break;
+ case 3:
+ playerpos.x=400,playerpos.y=400,playerrot=0;
+ frameleft=ThirtySeconds;
+ level=3,part=1;frms=0,averfps=0.0;restarts=0;bsscale=1.5;
+ towcnt=4;bulcnt=0;
+ memset(tower,0,sizeof(tower));
+ memset(bullet,0,sizeof(bullet));
+ mode=2;
+ score=0;
+ coll=semicoll=clrusg=0;
+ IfShowTip=true;
+ Complete=false;
+ Refliction=false;
+ Level3Part0();
+ IfCallLevel=true;
+ break;
+ case 4:
+ playerpos.x=400,playerpos.y=400,playerrot=0;
+ frameleft=TenSeconds;
+ level=1,part=1;frms=0,averfps=0.0;bsscale=1;
+ towcnt=bulcnt=0;
+ score=0;
+ coll=semicoll=clrusg=0;
+ memset(tower,0,sizeof(tower));
+ memset(bullet,0,sizeof(bullet));
+ Complete=false;
+ Refliction=false;
+ Level1Part1();
+ IfCallLevel=true;
+ mode=3;
+ break;
+ case 5:
+ Current_Position=0;
+ StartGUI->Leave();
+ gui->Enter();
+ }
+ }
+}
+void DeathGUI_Init()
+{
+ DeathGUI=new hgeGUI();
+ Current_Position=5;
+ DisableAllTower=true;DisablePlayer=true;
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,160,0.0f,"You Are Dead!"));
+ sprintf(ds1,"You scored %lld at level %d",score,level);
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,200,0.1f,ds1));
+ switch (mode)
+ {
+ case 1:sprintf(ds2,"Difficulty: Normal");break;
+ case 2:sprintf(ds2,"Difficulty: Extreme");break;
+ case 3:sprintf(ds2,"What Happened?! You died in Free Play Mode?!");break;
+ case 4:sprintf(ds2,"Difficulty: Easy");break;
+ }
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,240,0.2f,ds2));
+ sprintf(ds3,"Average FPS: %.2f",averfps);
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,280,0.3f,ds3));
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,320,0.3f,""));
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(6,fnt,snd,400,360,0.4f,"Continue from beginning of level? Your score will be set to minus!"));
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,400,0.5f,"Continue!"));
+ DeathGUI->AddCtrl(new hgeGUIMenuItem(8,fnt,snd,400,440,0.6f,"No thanks..."));
+ for (int i=1;i<=6;++i)DeathGUI->EnableCtrl(i,false);
+ DeathGUI->SetCursor(spr);
+ DeathGUI->SetNavMode(HGEGUI_UPDOWN|HGEGUI_CYCLED);
+ DeathGUI->SetFocus(7);
+ DeathGUI->Enter();
+}
+void DeathGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=DeathGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 7:
+ IfCallLevel=true;
+ Current_Position=1;
+ DeathGUI->Leave();
+ score=-abs(score);
+ ++restarts;
+ part=1;
+ clockrot=deltarot=0;
+ coll=towcnt=bulcnt=0;
+ DisableAllTower=DisablePlayer=false;
+ break;
+ case 8:Current_Position=0;gui->Enter();DeathGUI->Leave();break;
+ }
+ }
+}
+void NewHighScoreGUI_Init()
+{
+ Current_Position=7;
+ memset(newname,0,sizeof(newname));newlen=0;tbframebrk=0;toogleundl=false;
+ TipFont->SetColor(0xFFFFFFFF);
+}
+void nameins(char a)
+{
+ if (newlen<=14)
+ newname[newlen++]=a;
+}
+void namedel()
+{
+ if (newlen>0)newname[--newlen]=0;
+}
+void NewHighScoreGUI_FrameFnk()
+{
+ int key=hge->Input_GetKey();
+ if (key>=0x30&&key<=0x39)nameins('0'+key-0x30);
+ if (key>=0x41&&key<=0x5A)
+ nameins('a'+key-0x41);
+ if (key==HGEK_SPACE)nameins('_');
+ if (key==HGEK_BACKSPACE)namedel();
+ if (key==HGEK_ENTER)
+ {
+ InsertHighScore();
+ switch (mode)
+ {
+ case 4:view=1;HSViewGUI_Init();break;
+ case 1:view=2;HSViewGUI_Init();break;
+ case 2:view=3;HSViewGUI_Init();break;
+ case 3:view=4;HSViewGUI_Init();break;
+ }
+ }
+}
+void NewHighScoreGUI_Render()
+{
+ if (LOWFPS)tbframebrk+=17;else ++tbframebrk;
+ if (tbframebrk>=500)toogleundl=!toogleundl,tbframebrk=0;
+ TipFont->printf(200,200,HGETEXT_LEFT,"Please Enter Your Honorable Name...");
+ if (!toogleundl)
+ TipFont->printf(200,240,HGETEXT_LEFT,"%s",newname);
+ else
+ TipFont->printf(200,240,HGETEXT_LEFT,"%s_",newname);
+}
+void CompleteGUI_Init()
+{
+ CompleteGUI=new hgeGUI();
+ Current_Position=6;
+ DisableAllTower=true;DisablePlayer=true;
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,120,0.0f,"YOU DID THAT!"));
+ if (CheckHighScore()!=-1)
+ sprintf(hs1,"New Highscore %lld!",score);
+ else
+ sprintf(hs1,"Score %lld",score);
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,160,0.1f,hs1));
+ switch (mode)
+ {
+ case 1:
+ case 2:
+ case 4:sprintf(hs2,"Restarts %d",restarts);break;
+ case 3:sprintf(hs2,"Collisions %d",coll);break;
+ }
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,200,0.2f,hs2));
+ sprintf(hs3,"Semi-Collisions %d",semicoll);
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,240,0.3f,hs3));
+ sprintf(hs4,"CLR usage %d",clrusg);
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,280,0.3f,hs4));
+ sprintf(hs5,"Average FPS %.2f",averfps);
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(6,fnt,snd,400,320,0.4f,hs5));
+ if (CheckHighScore()!=-1)
+ {
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,360,0.5f,"Keep this in your record?"));
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(8,fnt,snd,400,400,0.6f,"Yes"));
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(9,fnt,snd,400,440,0.7f,"No thanks..."));
+ }
+ else
+ {
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,360,0.5f,""));
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(8,fnt,snd,400,400,0.6f,""));
+ CompleteGUI->AddCtrl(new hgeGUIMenuItem(9,fnt,snd,400,440,0.7f,"Back to menu"));
+ }
+ for (int i=1;i<=7;++i)CompleteGUI->EnableCtrl(i,false);
+ CompleteGUI->SetCursor(spr);
+ CompleteGUI->SetNavMode(HGEGUI_UPDOWN|HGEGUI_CYCLED);
+ CompleteGUI->SetFocus(7);
+ CompleteGUI->Enter();
+}
+void CompleteGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=CompleteGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 8:NewHighScoreGUI_Init();CompleteGUI->Leave();break;
+ case 9:Current_Position=0;gui->Enter();CompleteGUI->Leave();break;
+ }
+ }
+}
+void HSDetGUI_Init()
+{
+ HSDetailGUI=new hgeGUI();
+ Current_Position=10;
+ switch (view)
+ {
+ case 1:
+ memset(HSDetstr,0,sizeof(HSDetstr));
+ if (!ERec[detv].score)sprintf(HSDetstr[1],"Nothing here...");
+ else
+ {
+ sprintf(HSDetstr[1],"No. %d of Easy Mode",detv);
+ sprintf(HSDetstr[2],"Scored %lld by %s",ERec[detv].score,ERec[detv].name);
+ sprintf(HSDetstr[3],"Restarts %d",ERec[detv].rescol);
+ sprintf(HSDetstr[4],"Semi-Collisions %d",ERec[detv].scoll);
+ sprintf(HSDetstr[5],"CLR Usage %d",ERec[detv].clrusg);
+ sprintf(HSDetstr[6],"Average FPS %d.%d",ERec[detv].af_int,ERec[detv].af_fric);
+ }
+ for (int i=1;i<=6;++i)
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(i,fnt,snd,400,170+30*i,0.1f*i-0.1f,HSDetstr[i])),
+ HSDetailGUI->EnableCtrl(i,false);
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,380,0.6f,"Back"));
+ break;
+ case 2:
+ memset(HSDetstr,0,sizeof(HSDetstr));
+ if (!NRec[detv].score)sprintf(HSDetstr[1],"Nothing here...");
+ else
+ {
+ sprintf(HSDetstr[1],"No. %d of Normal Mode",detv);
+ sprintf(HSDetstr[2],"Scored %lld by %s",NRec[detv].score,NRec[detv].name);
+ sprintf(HSDetstr[3],"Restarts %d",NRec[detv].rescol);
+ sprintf(HSDetstr[4],"Semi-Collisions %d",NRec[detv].scoll);
+ sprintf(HSDetstr[5],"CLR Usage %d",NRec[detv].clrusg);
+ sprintf(HSDetstr[6],"Average FPS %d.%d",NRec[detv].af_int,NRec[detv].af_fric);
+ }
+ for (int i=1;i<=6;++i)
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(i,fnt,snd,400,170+30*i,0.1f*i-0.1f,HSDetstr[i])),
+ HSDetailGUI->EnableCtrl(i,false);
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,380,0.6f,"Back"));
+ break;
+ case 3:
+ memset(HSDetstr,0,sizeof(HSDetstr));
+ if (!ExRec[detv].score)sprintf(HSDetstr[1],"Nothing here...");
+ else
+ {
+ sprintf(HSDetstr[1],"No. %d of Extreme Mode",detv);
+ sprintf(HSDetstr[2],"Scored %lld by %s",ExRec[detv].score,ExRec[detv].name);
+ sprintf(HSDetstr[3],"Restarts %d",ExRec[detv].rescol);
+ sprintf(HSDetstr[4],"Semi-Collisions %d",ExRec[detv].scoll);
+ sprintf(HSDetstr[5],"CLR Usage %d",ExRec[detv].clrusg);
+ sprintf(HSDetstr[6],"Average FPS %d.%d",ExRec[detv].af_int,ExRec[detv].af_fric);
+ }
+ for (int i=1;i<=6;++i)
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(i,fnt,snd,400,170+30*i,0.1f*i-0.1f,HSDetstr[i])),
+ HSDetailGUI->EnableCtrl(i,false);
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,380,0.6f,"Back"));
+ break;
+ case 4:
+ memset(HSDetstr,0,sizeof(HSDetstr));
+ if (!FPMRec[detv].score)sprintf(HSDetstr[1],"Nothing here...");
+ else
+ {
+ sprintf(HSDetstr[1],"No. %d of Free Play Mode",detv);
+ sprintf(HSDetstr[2],"Scored %lld by %s",FPMRec[detv].score,FPMRec[detv].name);
+ sprintf(HSDetstr[3],"Collisions %d",FPMRec[detv].rescol);
+ sprintf(HSDetstr[4],"Semi-Collisions %d",FPMRec[detv].scoll);
+ sprintf(HSDetstr[5],"CLR Usage %d",FPMRec[detv].clrusg);
+ sprintf(HSDetstr[6],"Average FPS %d.%d",FPMRec[detv].af_int,FPMRec[detv].af_fric);
+ }
+ for (int i=1;i<=6;++i)
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(i,fnt,snd,400,170+30*i,0.1f*i-0.1f,HSDetstr[i])),
+ HSDetailGUI->EnableCtrl(i,false);
+ HSDetailGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,380,0.6f,"Back"));
+ break;
+ }
+ HSDetailGUI->SetCursor(spr);
+ HSDetailGUI->SetNavMode(HGEGUI_UPDOWN);
+ HSDetailGUI->SetFocus(7);
+ HSDetailGUI->Enter();
+}
+void HSDetGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=HSDetailGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 7:Current_Position=9;HSDetailGUI->Leave();HSViewGUI->Enter();break;
+ }
+ }
+}
+void HSViewGUI_Init()
+{
+ Current_Position=9;
+ HSViewGUI=new hgeGUI();
+ switch (view)
+ {
+ case 1:
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Highscore - Easy"));
+ for (int i=1;i<=Ecnt;++i)
+ {
+ sprintf(HSVstr[i],"%d. %s - %lld",i,ERec[i].name,ERec[i].score);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ for (int i=Ecnt+1;i<=5;++i)
+ {
+ sprintf(HSVstr[i],"%d. ----------",i);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ break;
+ case 2:
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Highscore - Normal"));
+ for (int i=1;i<=Ncnt;++i)
+ {
+ sprintf(HSVstr[i],"%d. %s - %lld",i,NRec[i].name,NRec[i].score);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ for (int i=Ncnt+1;i<=5;++i)
+ {
+ sprintf(HSVstr[i],"%d. ----------",i);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ break;
+ case 3:
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Highscore - Extreme"));
+ for (int i=1;i<=Excnt;++i)
+ {
+ sprintf(HSVstr[i],"%d. %s - %lld",i,ExRec[i].name,ExRec[i].score);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ for (int i=Excnt+1;i<=5;++i)
+ {
+ sprintf(HSVstr[i],"%d. ----------",i);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ break;
+ case 4:
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Highscore - Free Play Mode"));
+ for (int i=1;i<=FPMcnt;++i)
+ {
+ sprintf(HSVstr[i],"%d. %s - %lld",i,FPMRec[i].name,FPMRec[i].score);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ for (int i=FPMcnt+1;i<=5;++i)
+ {
+ sprintf(HSVstr[i],"%d. ----------",i);
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(i+1,fnt,snd,400,200+30*i,0.1f*i,HSVstr[i]));
+ }
+ break;
+ }
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(7,fnt,snd,400,380,0.6f,"Select one record to view details."));
+ HSViewGUI->AddCtrl(new hgeGUIMenuItem(8,fnt,snd,400,410,0.7f,"Back"));
+ HSViewGUI->EnableCtrl(1,false);HSViewGUI->EnableCtrl(7,false);
+ HSViewGUI->SetCursor(spr);
+ HSViewGUI->SetNavMode(HGEGUI_UPDOWN|HGEGUI_CYCLED);
+ HSViewGUI->SetFocus(2);
+ HSViewGUI->Enter();
+}
+void HSViewGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=HSViewGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 2:detv=1;HSDetGUI_Init();break;
+ case 3:detv=2;HSDetGUI_Init();break;
+ case 4:detv=3;HSDetGUI_Init();break;
+ case 5:detv=4;HSDetGUI_Init();break;
+ case 6:detv=5;HSDetGUI_Init();break;
+ case 8:Current_Position=8;HSViewGUI->Leave();if (!HighScoreGUI)HighScoreGUI_Init();HighScoreGUI->Enter();break;
+ }
+ }
+}
+void HighScoreGUI_Init()
+{
+ HighScoreGUI=new hgeGUI();
+ Current_Position=8;
+ HighScoreGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,350,200,0.0f,"View Highscores && Records for..."));
+ HighScoreGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,"Easy"));
+ HighScoreGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,"Normal"));
+ HighScoreGUI->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,"Extreme"));
+ HighScoreGUI->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Free Play Mode"));
+ HighScoreGUI->AddCtrl(new hgeGUIMenuItem(6,fnt,snd,400,400,0.5f,"Back"));
+ HighScoreGUI->EnableCtrl(1,false);
+ HighScoreGUI->SetCursor(spr);
+ HighScoreGUI->SetNavMode(HGEGUI_UPDOWN|HGEGUI_CYCLED);
+ HighScoreGUI->SetFocus(7);
+ HighScoreGUI->Enter();
+}
+void HighScoreGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=HighScoreGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 2:view=1;HSViewGUI_Init();break;
+ case 3:view=2;HSViewGUI_Init();break;
+ case 4:view=3;HSViewGUI_Init();break;
+ case 5:view=4;HSViewGUI_Init();break;
+ case 6:Current_Position=0;HighScoreGUI->Leave();gui->Enter();break;
+ }
+ }
+
+}
+void BkTTitleGUI_Init()
+{
+ BkTTitleGUI=new hgeGUI();
+ Current_Position=12;
+ BkTTitleGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Really?"));
+ BkTTitleGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,200,250,0.1f,"I've pressed the wrong key"));
+ BkTTitleGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,600,250,0.2f,"Do return to menu!"));
+ BkTTitleGUI->EnableCtrl(1,false);
+ BkTTitleGUI->SetCursor(spr);
+ BkTTitleGUI->SetNavMode(HGEGUI_LEFTRIGHT|HGEGUI_CYCLED);
+ BkTTitleGUI->SetFocus(2);
+ BkTTitleGUI->Enter();
+}
+void BkTTitleGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=BkTTitleGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 2:
+ BkTTitleGUI->Leave();
+ Current_Position=11;
+ PauseGUI_Init();
+ break;
+ case 3:
+ Current_Position=0;BkTTitleGUI->Leave();gui->Enter();
+ break;
+ }
+ }
+}
+void PauseGUI_Init()
+{
+ PauseGUI=new hgeGUI();
+ Current_Position=11;
+ DisableAllTower=DisablePlayer=true;
+ PauseGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,"Paused..."));
+ PauseGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,"Return to Game"));
+ PauseGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,"Return to Title"));
+ PauseGUI->EnableCtrl(1,false);
+ PauseGUI->SetCursor(spr);
+ PauseGUI->SetNavMode(HGEGUI_UPDOWN|HGEGUI_CYCLED);
+ PauseGUI->SetFocus(2);
+ PauseGUI->Enter();
+}
+void PauseGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=PauseGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 2:
+ PauseGUI->Leave();
+ Current_Position=1;
+ DisableAllTower=DisablePlayer=false;
+ break;
+ case 3:
+ BkTTitleGUI_Init();
+ break;
+ }
+ }
+}
+int AP_Update(int plrspd,int plrslospd,int clrbns)
+{
+ int res=0;
+ if (plrspd<=4)res+=plrspd*1200;else res+=5000;
+ switch (plrslospd)
+ {
+ case 1:res+=4000;break;
+ case 2:res+=3200;break;
+ case 3:res+=2000;break;
+ case 4:res+=1500;break;
+ case 5:res+=700;break;
+ }
+ switch (clrbns)
+ {
+ case 0:break;
+ case 1:res+=1500;break;
+ case 2:res+=2700;break;
+ case 3:res+=4000;break;
+ case 4:res+=5500;break;
+ }
+ return res;
+}
+void Options_Writeback()
+{
+ freopen("blr.cfg","w",stdout);
+ printf(";CBL");
+ printf("%c",fpslvl==1?1:0);
+ printf("%c",tfs?1:0);
+ printf("%c",fpslvl==2?1:0);
+ printf("%c",diffkey?1:0);
+ printf("%c%c%c",plrspd,plrslospd,clrbns);
+ fclose(stdout);
+}
+void OptionsGUI_Init()
+{
+ OptionsGUI=new hgeGUI();
+ Current_Position=13;
+ if (!tfs)
+ sprintf(opt[0],"Fullscreen: Off");
+ else
+ sprintf(opt[0],"Fullscreen: On");
+ OptionsGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,opt[0]));
+ switch (fpslvl)
+ {
+ case 0:sprintf(opt[1],"FPS Level: Natural");break;
+ case 1:sprintf(opt[1],"FPS Level: Low FPS");break;
+ case 2:sprintf(opt[1],"FPS Level: Highest");break;
+ }
+ OptionsGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,opt[1]));
+ if (diffkey)
+ sprintf(opt[2],"Use Key X for Clear Range");
+ else
+ sprintf(opt[2],"Use Key Z for Clear Range");
+ OptionsGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,opt[2]));
+ OptionsGUI->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,"Player Profile"));
+ OptionsGUI->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Save and Exit"));
+ OptionsGUI->SetNavMode(HGEGUI_UPDOWN);
+ OptionsGUI->SetCursor(spr);
+ OptionsGUI->SetFocus(1);
+ OptionsGUI->Enter();
+}
+void PlayerProfGUI_Init()
+{
+ PlayerProfGUI=new hgeGUI();
+ Current_Position=14;
+ sprintf(opt[3],"Moving Speed: -%d+",plrspd);
+ sprintf(opt[4],"Precise Moving Speed: -%d+",plrslospd);
+ sprintf(opt[5],"Clear Range Bonus: -%d+",clrbns);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ PlayerProfGUI->AddCtrl(new hgeGUIMenuItem(1,fnt,snd,400,200,0.0f,opt[3]));
+ PlayerProfGUI->AddCtrl(new hgeGUIMenuItem(2,fnt,snd,400,240,0.1f,opt[4]));
+ PlayerProfGUI->AddCtrl(new hgeGUIMenuItem(3,fnt,snd,400,280,0.2f,opt[5]));
+ PlayerProfGUI->AddCtrl(new hgeGUIMenuItem(4,fnt,snd,400,320,0.3f,opt[6]));
+ PlayerProfGUI->AddCtrl(new hgeGUIMenuItem(5,fnt,snd,400,360,0.4f,"Back"));
+ PlayerProfGUI->SetNavMode(HGEGUI_UPDOWN);
+ PlayerProfGUI->SetCursor(spr);
+ PlayerProfGUI->SetFocus(1);
+ PlayerProfGUI->Enter();
+}
+void PlayerProfGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=PlayerProfGUI->Update(dt);
+ if (id==5&&AP_Update(plrspd,plrslospd,clrbns)<=10000)
+ {PlayerProfGUI->Leave();OptionsGUI_Init();}
+ if (hge->Input_GetKeyState(HGEK_LEFT))
+ {
+ if (!LOWFPS)++lastkeypressed;else lastkeypressed+=17;
+ if (lastkeypressed>=100)
+ {
+ switch (PlayerProfGUI->GetFocus())
+ {
+ case 1:
+ if (plrspd>1)--plrspd;
+ sprintf(opt[3],"Moving Speed: -%d+",plrspd);
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(1))->RePos(400,200);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(4))->RePos(400,320);
+ break;
+ case 2:
+ if (plrslospd>1)--plrslospd;
+ sprintf(opt[4],"Precise Moving Speed: -%d+",plrslospd);
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(2))->RePos(400,240);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(4))->RePos(400,320);
+ break;
+ case 3:
+ if (clrbns>0)--clrbns;
+ sprintf(opt[5],"Clear Range Bonus: -%d+",clrbns);
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(3))->RePos(400,280);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(4))->RePos(400,320);
+ break;
+ }
+ lastkeypressed=0;
+ }
+ }
+ if (hge->Input_GetKeyState(HGEK_RIGHT))
+ {
+ if (!LOWFPS)++lastkeypressed;else lastkeypressed+=17;
+ if (lastkeypressed>=100)
+ {
+ switch (PlayerProfGUI->GetFocus())
+ {
+ case 1:
+ if (plrspd<5)++plrspd;
+ sprintf(opt[3],"Moving Speed: -%d+",plrspd);
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(1))->RePos(400,200);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(4))->RePos(400,320);
+ break;
+ case 2:
+ if (plrslospd<5)++plrslospd;
+ sprintf(opt[4],"Precise Moving Speed: -%d+",plrslospd);
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(2))->RePos(400,240);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(4))->RePos(400,320);
+ break;
+ case 3:
+ if (clrbns<4)++clrbns;
+ sprintf(opt[5],"Clear Range Bonus: -%d+",clrbns);
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(3))->RePos(400,280);
+ sprintf(opt[6],"Ability Point %d/10000",AP_Update(plrspd,plrslospd,clrbns));
+ ((hgeGUIMenuItem*)PlayerProfGUI->GetCtrl(4))->RePos(400,320);
+ break;
+ }
+ lastkeypressed=0;
+ }
+ }
+}
+void OptionsGUI_FrameFnk()
+{
+ float dt=hge->Timer_GetDelta();
+ int id=OptionsGUI->Update(dt);
+ if (id)
+ {
+ switch (id)
+ {
+ case 1:
+ tfs=!tfs;
+ if (!tfs)
+ sprintf(opt[0],"Fullscreen: Off");
+ else
+ sprintf(opt[0],"Fullscreen: On");
+ ((hgeGUIMenuItem*)OptionsGUI->GetCtrl(1))->RePos(400,200);
+ break;
+ case 2:
+ switch (fpslvl)
+ {
+ case 0:
+ fpslvl=1;LOWFPS=true;
+ hge->System_SetState(HGE_FPS,61);
+ break;
+ case 1:
+ fpslvl=2;LOWFPS=false;
+ hge->System_SetState(HGE_FPS,1000);
+ break;
+ case 2:
+ fpslvl=0;LOWFPS=false;
+ hge->System_SetState(HGE_FPS,0);
+ break;
+ }
+ switch (fpslvl)
+ {
+ case 0:sprintf(opt[1],"FPS Level: Natural");break;
+ case 1:sprintf(opt[1],"FPS Level: Low FPS");break;
+ case 2:sprintf(opt[1],"FPS Level: Highest");break;
+ }
+ ((hgeGUIMenuItem*)OptionsGUI->GetCtrl(2))->RePos(400,240);
+ break;
+ case 3:
+ diffkey=!diffkey;
+ if (diffkey)
+ sprintf(opt[2],"Use Key X for Clear Range");
+ else
+ sprintf(opt[2],"Use Key Z for Clear Range");
+ ((hgeGUIMenuItem*)OptionsGUI->GetCtrl(3))->RePos(400,280);
+ break;
+ case 4:
+ PlayerProfGUI_Init();
+ break;
+ case 5:
+ Options_Writeback();
+ OptionsGUI->Leave();
+ gui->Enter();
+ Current_Position=0;
+ break;
+ }
+ }
+}
diff --git a/archive/blr1/src/scorec.h b/archive/blr1/src/scorec.h new file mode 100644 index 0000000..d07615a --- /dev/null +++ b/archive/blr1/src/scorec.h @@ -0,0 +1,252 @@ +//Chrisoft Bullet Lab Remix HGE
+//Score Recording Implementations
+//"Copyleft" Chrisoft 2013
+struct TRecord
+{
+ long long score;
+ int len,rescol,scoll,clrusg;
+ int af_int,af_fric;
+ char name[16];
+}ERec[10],NRec[10],ExRec[10],FPMRec[10];
+unsigned int Ecnt,Ncnt,Excnt,FPMcnt;
+unsigned int header,seprt;
+char newname[16];
+int newlen,tbframebrk;
+unsigned int Getuint()
+{
+ unsigned int c1,c2,c3,c4,res;
+ c1=c2=c3=c4=0;
+ scanf("%c%c%c%c",&c1,&c2,&c3,&c4);
+ res=(c1<<24)+(c2<<16)+(c3<<8)+c4;
+ return res;
+}
+int Getint()
+{
+ return (int)Getuint();
+}
+long long Getll()
+{
+ long long c1,c2,c3,c4,c5,c6,c7,c8,res;
+ c1=c2=c3=c4=c5=c6=c7=c8=0;
+ scanf("%c%c%c%c%c%c%c%c",&c1,&c2,&c3,&c4,&c5,&c6,&c7,&c8);
+ res=(c1<<56)+(c2<<48)+(c3<<40)+(c4<<32)+(c5<<24)+(c6<<16)+(c7<<8)+c8;
+ return res;
+}
+void Putuint(unsigned int a)
+{
+ unsigned int c1,c2,c3,c4;
+ c1=a&0xFF000000;c2=a&0x00FF0000;
+ c3=a&0x0000FF00;c4=a&0x000000FF;
+ printf("%c%c%c%c",c1,c2,c3,c4);
+}
+void Putint(int a)
+{
+ Putuint((unsigned int)a);
+}
+void Putll(long long a)
+{
+ int c1,c2,c3,c4,c5,c6,c7,c8;
+ c1=a&0xFF00000000000000;
+ c2=a&0x00FF000000000000;
+ c3=a&0x0000FF0000000000;
+ c4=a&0x000000FF00000000;
+ c5=a&0x00000000FF000000;
+ c6=a&0x0000000000FF0000;
+ c7=a&0x000000000000FF00;
+ c8=a&0x00000000000000FF;
+ printf("%c%c%c%c%c%c%c%c",c1,c2,c3,c4,c5,c6,c7,c8);
+}
+TRecord GetTRecord()
+{
+ TRecord res;
+ res.len=Getint();
+ memset(res.name,0,sizeof(res.name));
+ for (int i=0;i<res.len;++i)scanf("%c",&res.name[i]);
+ res.score=Getll();
+ res.rescol=Getint();
+ res.scoll=Getint();
+ res.clrusg=Getint();
+ res.af_int=Getint();res.af_fric=Getint();
+ return res;
+}
+void PutTRecord(TRecord a)
+{
+ Putint(a.len);
+ for (int i=0;i<a.len;++i)printf("%c",a.name[i]);
+ Putll(a.score);
+ Putint(a.rescol);
+ Putint(a.scoll);
+ Putint(a.clrusg);
+ Putint(a.af_int);Putint(a.af_fric);
+}
+void Score_Init()
+{
+ freopen("score.cfg","r",stdin);
+ header=Getuint();
+ if (header!=0x3b424c53)//0x3b424c53=";BLS"
+ {
+ fclose(stdin);
+ Error("Error when loading score file!");
+ }
+ seprt=Getuint();
+ if (seprt!=0xd1ffa0c0)
+ {
+ fclose(stdin);
+ Error("Error when loading score file!");
+ }
+ Ecnt=Getuint();
+ for (unsigned int i=1;i<=Ecnt;++i)ERec[i]=GetTRecord();
+ seprt=Getuint();
+ if (seprt!=0xd1ffa0c1)
+ {
+ fclose(stdin);
+ Error("Error when loading score file!");
+ }
+ Ncnt=Getuint();
+ for (unsigned int i=1;i<=Ncnt;++i)NRec[i]=GetTRecord();
+ seprt=Getuint();
+ if (seprt!=0xd1ffa0c2)
+ {
+ fclose(stdin);
+ Error("Error when loading score file!");
+ }
+ Excnt=Getuint();
+ for (unsigned int i=1;i<=Excnt;++i)ExRec[i]=GetTRecord();
+ seprt=Getuint();
+ if (seprt!=0xd1ffa0c3)
+ {
+ fclose(stdin);
+ Error("Error when loading score file!");
+ }
+ FPMcnt=Getuint();
+ for (unsigned int i=1;i<=FPMcnt;++i)FPMRec[i]=GetTRecord();
+ fclose(stdin);
+}
+int CheckHighScore()
+{
+ int i;
+ switch (mode)
+ {
+ case 4:
+ for (i=1;i<=Ecnt;++i)
+ if (ERec[i].score<score)break;
+ if (i==5&&ERec[i].score>score)return -1;
+ if (Ecnt<5&&ERec[Ecnt].score>score)return Ecnt+1;
+ return i;
+ break;
+ case 1:
+ for (i=1;i<=Ncnt;++i)
+ if (NRec[i].score<score)break;
+ if (i==5&&NRec[i].score>score)return -1;
+ if (Ncnt<5&&NRec[Ncnt].score>score)return Ncnt+1;
+ return i;
+ break;
+ case 2:
+ for (i=1;i<=Excnt;++i)
+ if (ExRec[i].score<score)break;
+ if (i==5&&ExRec[i].score>score)return -1;
+ if (Excnt<5&&ExRec[Ncnt].score>score)return Excnt+1;
+ return i;
+ break;
+ case 3:
+ for (i=1;i<=FPMcnt;++i)
+ if (FPMRec[i].score<score)break;
+ if (i==5&&FPMRec[i].score>score)return -1;
+ if (FPMcnt<5&&FPMRec[Ncnt].score>score)return FPMcnt+1;
+ return i;
+ break;
+ }
+}
+void Score_Write()
+{
+ freopen("score.cfg","w",stdout);
+ Putuint(0x3b424c53u);
+ Putuint(0xd1ffa0c0u);
+ Putint(Ecnt);
+ for (int i=1;i<=Ecnt;++i)
+ PutTRecord(ERec[i]);
+ Putuint(0xd1ffa0c1u);
+ Putint(Ncnt);
+ for (int i=1;i<=Ncnt;++i)
+ PutTRecord(NRec[i]);
+ Putuint(0xd1ffa0c2u);
+ Putint(Excnt);
+ for (int i=1;i<=Excnt;++i)
+ PutTRecord(ExRec[i]);
+ Putuint(0xd1ffa0c3u);
+ Putint(FPMcnt);
+ for (int i=1;i<=FPMcnt;++i)
+ PutTRecord(FPMRec[i]);
+ fclose(stdout);
+}
+void Score_Initailize()
+{
+ freopen("score.cfg","w",stdout);
+ printf(";BLS");
+ printf("%c%c%c%c",0xd1,0xff,0xa0,0xc0);printf("%c%c%c%c",0,0,0,0);
+ printf("%c%c%c%c",0xd1,0xff,0xa0,0xc1);printf("%c%c%c%c",0,0,0,0);
+ printf("%c%c%c%c",0xd1,0xff,0xa0,0xc2);printf("%c%c%c%c",0,0,0,0);
+ printf("%c%c%c%c",0xd1,0xff,0xa0,0xc3);printf("%c%c%c%c",0,0,0,0);
+ fclose(stdout);
+}
+void InsertHighScore()
+{
+ int pos=CheckHighScore();
+ switch (mode)
+ {
+ case 4:
+ if (pos<=Ecnt)
+ for (int i=5;i>pos;--i)
+ ERec[i]=ERec[i-1];
+ else ++Ecnt;
+ if (Ecnt<5)++Ecnt;
+ ERec[pos].score=score;
+ ERec[pos].len=newlen;
+ memcpy(ERec[pos].name,newname,sizeof(newname));
+ ERec[pos].clrusg=clrusg;
+ ERec[pos].rescol=restarts;ERec[pos].scoll=semicoll;
+ ERec[pos].af_int=(int)averfps;
+ ERec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10;
+ break;
+ case 1:
+ if (pos<=Ncnt)
+ for (int i=5;i>pos;--i)
+ NRec[i]=NRec[i-1];
+ if (Ncnt<5)++Ncnt;
+ NRec[pos].score=score;
+ NRec[pos].len=newlen;
+ memcpy(NRec[pos].name,newname,sizeof(newname));
+ NRec[pos].clrusg=clrusg;
+ NRec[pos].rescol=restarts;NRec[pos].scoll=semicoll;
+ NRec[pos].af_int=(int)averfps;
+ NRec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10;
+ break;
+ case 2:
+ if (pos<=Excnt)
+ for (int i=5;i>pos;--i)
+ ExRec[i]=ExRec[i-1];
+ if (Excnt<5)++Excnt;
+ ExRec[pos].score=score;
+ ExRec[pos].len=newlen;
+ memcpy(ExRec[pos].name,newname,sizeof(newname));
+ ExRec[pos].clrusg=clrusg;
+ ExRec[pos].rescol=restarts;ExRec[pos].scoll=semicoll;
+ ExRec[pos].af_int=(int)averfps;
+ ExRec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10;
+ break;
+ case 3:
+ if (pos<=FPMcnt)
+ for (int i=5;i>pos;--i)
+ FPMRec[i]=FPMRec[i-1];
+ if (FPMcnt<5)++FPMcnt;
+ FPMRec[pos].score=score;
+ FPMRec[pos].len=newlen;
+ memcpy(FPMRec[pos].name,newname,sizeof(newname));
+ FPMRec[pos].clrusg=clrusg;
+ FPMRec[pos].rescol=coll;FPMRec[pos].scoll=semicoll;
+ FPMRec[pos].af_int=(int)averfps;
+ FPMRec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10;
+ break;
+ }
+ Score_Write();
+}
\ No newline at end of file diff --git a/archive/blr1/src/towernbullet.h b/archive/blr1/src/towernbullet.h new file mode 100644 index 0000000..6cae63d --- /dev/null +++ b/archive/blr1/src/towernbullet.h @@ -0,0 +1,983 @@ +//Chrisoft Bullet Lab Remix HGE
+//Towers and Bullets Implementations
+//"Copyleft" Chrisoft 2013
+//WANTED:
+//Human-being which really knows what these mean, please contact Chirsno which is puzzled by these shitty codes..
+#include "effects.h"
+int CreateBullet1(double x,double y,double bs,bool eff=false)
+{
+ ++shots;
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=1;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=x-playerpos.x;
+ bullet[i].bulletdir.y=y-playerpos.y;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=bs;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,23,0,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ bullet[i].scollable=true;
+ bullet[i].scale=1;
+ bullet[i].bulletspr->SetHotSpot(12,12);
+ if (eff)BulletEffect_Attatch(i);
+ return i;
+}
+void CreateBullet2(double x,double y,double bs,double rad,bool eff=false)
+{
+ ++shots;
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=2;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=cos(rad);
+ bullet[i].bulletdir.y=sin(rad);
+ bullet[i].bulletspeed=bs;
+ bullet[i].lifetime=0;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,0,0,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ bullet[i].scollable=true;
+ bullet[i].scale=1;
+ bullet[i].bulletspr->SetHotSpot(12,12);
+ if (eff)BulletEffect_Attatch(i);
+}
+void CreateBullet3(double x,double y,double bs,int dir,bool eff=false)
+{
+ CreateBullet2(x,y,bs,dir*0.5235987756,eff);
+}
+void CreateBullet4(double x,double y,double bs,int yelbrk=0,bool eff=false)
+{
+ ++shots;
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=4;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=x-playerpos.x;
+ bullet[i].bulletdir.y=y-playerpos.y;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=bs;
+ bullet[i].yelbrk=yelbrk;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,0,46,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ bullet[i].scollable=true;
+ bullet[i].scale=1;
+ bullet[i].bulletspr->SetHotSpot(12,12);
+ if (eff)BulletEffect_Attatch(i);
+}
+void CreateBullet5(double x,double y,double bs,bool eff=false)
+{
+ ++shots;
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=5;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=x-playerpos.x;
+ bullet[i].bulletdir.y=y-playerpos.y;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=bs;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,0,23,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ bullet[i].scollable=true;
+ bullet[i].scale=1;
+ bullet[i].bulletspr->SetHotSpot(12,12);
+ if (eff)BulletEffect_Attatch(i);
+}
+int CreateBullet6(double x,double y,double bs,int explo,bool eff=false)
+{
+ ++shots;
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=6;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=rand()%100-50;
+ bullet[i].bulletdir.y=rand()%100-50;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=bs;
+ bullet[i].oriexplo=bullet[i].redexplo=explo;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,23,23,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ bullet[i].scollable=true;
+ bullet[i].scale=1;
+ bullet[i].bulletspr->SetHotSpot(12,12);
+ if (eff)BulletEffect_Attatch(i);
+ return i;
+}
+int CreateBullet7(double x,double y,double bs,int explo,bool eff=false)
+{
+ ++shots;
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=7;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=rand()%100-50;
+ bullet[i].bulletdir.y=rand()%100-50;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=bs;
+ bullet[i].oriexplo=bullet[i].redexplo=explo;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,46,23,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+ bullet[i].redattrib=0;
+ bullet[i].whirem=whicnt;
+ bullet[i].whiskp=0;
+ bullet[i].scollable=true;
+ bullet[i].scale=1;
+ bullet[i].bulletspr->SetHotSpot(12,12);
+ if (eff)BulletEffect_Attatch(i);
+ return i;
+}
+void CreateBullet255(double x,double y,double bs)
+{
+ int i;
+ if (bulcnt==0)
+ bulcnt=i=1;
+ else
+ {
+ for (i=1;i<=bulcnt;++i)
+ if (!bullet[i].exist)break;
+ if (i>bulcnt)bulcnt=i;
+ }
+ bullet[i].exist=true;
+ bullet[i].bullettype=255;
+ bullet[i].bulletpos.x=x;
+ bullet[i].bulletpos.y=y;
+ bullet[i].bulletdir.x=x-playerpos.x;
+ bullet[i].bulletdir.y=y-playerpos.y;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ bullet[i].bulletspeed=bs;
+ bullet[i].bulletspr=new hgeSprite(SprSheet1,46,0,24,24);
+ bullet[i].bulletspr->SetColor(0x80FFFFFF);
+}
+void ProcessBullet1()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=1)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ }
+ BulletEffect_Process(i);
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ if (dis<=6)++coll,scminus+=10000;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0);
+ if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch();
+ }
+ }
+}
+void ProcessBullet2()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=2)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (LOWFPS)bullet[i].lifetime+=17;else ++bullet[i].lifetime;
+ if (bullet[i].lifetime>=15000&&Refliction)
+ {
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ continue;
+ }
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y)/20;//Process bullet's y coor.
+ }
+ }
+ BulletEffect_Process(i);
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ {
+ if (Refliction)
+ bullet[i].bulletdir.x=-bullet[i].bulletdir.x,
+ bullet[i].bulletdir.y=-bullet[i].bulletdir.y;
+ else
+ {
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ continue;
+ }
+ }
+ if (dis<=6)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ ++coll,scminus+=10000;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ continue;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0);
+ if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch();
+ }
+ }
+}
+//There is no need for ProcessBullet3() because they are in fact bullet2
+void ProcessBullet4()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=4)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ bullet[i].whirem+=17;
+ else
+ ++bullet[i].whirem;
+ if ((yelattrib&&bullet[i].whirem>=bullet[i].yelbrk)||!yelattrib)
+ {
+ bullet[i].whirem=0;
+ bullet[i].bulletdir.x=bullet[i].bulletpos.x-playerpos.x;
+ bullet[i].bulletdir.y=bullet[i].bulletpos.y-playerpos.y;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ }
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ //bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ //bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ BulletEffect_Process(i);
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ if (dis<=6)++coll,scminus+=10000;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0);
+ if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch();
+ }
+ }
+}
+void ProcessBullet5()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=5)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ //bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ //bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ BulletEffect_Process(i);
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ if (dis<=6)playerspeed*=0.9,playerslospeed*=0.9;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0);
+ }
+ }
+}
+void ProcessBullet6()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=6)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ //bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ //bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ BulletEffect_Process(i);
+ if (!LOWFPS)
+ {
+ if (bullet[i].redattrib==0)
+ --bullet[i].redexplo;
+ else
+ bullet[i].redexplo-=2;
+ }
+ else
+ {
+ if (bullet[i].redattrib==0)
+ bullet[i].redexplo-=17;
+ else
+ bullet[i].redexplo-=34;
+ }
+ if (bullet[i].redexplo<=0&&!DisableAllTower)
+ {
+ if (bullet[i].redattrib==0)
+ {
+ for (int j=1;j<=8;++j)
+ {
+ int pnt=CreateBullet6(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,bullet[i].oriexplo);
+ //hge->Effect_PlayEx(snd,100,(bullet[i].bulletpos.x-400)/4);
+ bullet[pnt].bulletdir.x=cos(j*0.785398);
+ bullet[pnt].bulletdir.y=sin(j*0.785398);
+ bullet[pnt].dist=bullet[pnt].bulletdir.x*bullet[pnt].bulletdir.x+bullet[pnt].bulletdir.y*bullet[pnt].bulletdir.y;
+ bullet[pnt].dist=sqrt(bullet[pnt].dist);
+ bullet[pnt].redattrib=1;
+ }
+ }
+ else
+ {
+ for (int j=1;j<=12;++j)
+ CreateBullet2(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,j*0.5236+clockrot);
+ clockrot+=deltarot;
+ deltarot+=0.004363322313;
+ }
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ if (dis<=6)++coll,scminus+=10000;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0);
+ if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch();
+ }
+ }
+}
+void ProcessBullet7()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=7)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ //bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ //bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ BulletEffect_Process(i);
+ if (!LOWFPS)
+ {
+ if (bullet[i].redattrib==0)
+ --bullet[i].redexplo;
+ else
+ bullet[i].redexplo-=3;
+ }
+ else
+ {
+ if (bullet[i].redattrib==0)
+ bullet[i].redexplo-=17;
+ else
+ bullet[i].redexplo-=51;
+ }
+ if (bullet[i].redexplo<=0&&!DisableAllTower)
+ {
+ if (bullet[i].redattrib==0)
+ {
+ int pnt=CreateBullet7(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,bullet[i].oriexplo);
+ //hge->Effect_PlayEx(snd,100,(bullet[i].bulletpos.x-400)/4);
+ bullet[pnt].bulletdir.x=0;
+ bullet[pnt].bulletdir.y=0;
+ bullet[pnt].dist=1;
+ bullet[pnt].redattrib=1;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ if (!LOWFPS)
+ ++bullet[i].whiskp;
+ else
+ bullet[i].whiskp+=17;
+ if (bullet[i].whiskp>50)
+ {
+ for (int j=1;j<=12;++j)
+ CreateBullet2(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,j*0.5236+whirot);
+ whirot+=dwhirot;
+ dwhirot+=0.004363322313;
+ bullet[i].whiskp=0;
+ --bullet[i].whirem;
+ }
+ if (bullet[i].whirem<=0)
+ {
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ }
+ }
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ if (dis<=6)++coll,scminus+=10000;
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0);
+ if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch();
+ }
+ }
+}
+void ProcessBullet255()
+{
+ for (int i=1;i<=bulcnt;++i)
+ {
+ if (!bullet[i].exist||bullet[i].bullettype!=255)continue;//If this bullet doesn't exist or is not of this type, do not render it.
+ if (!DisablePlayer)
+ {
+ bullet[i].bulletdir.x=bullet[i].bulletpos.x-playerpos.x;
+ bullet[i].bulletdir.y=bullet[i].bulletpos.y-playerpos.y;
+ bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y;
+ bullet[i].dist=sqrt(bullet[i].dist);
+ if (LOWFPS)
+ {
+ bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17;//Process bullet's y coor.
+ }
+ else
+ {
+ bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ //bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20;//Process bullet's x coor.
+ //bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20;//Process bullet's y coor.
+ }
+ double dis=GetDist(bullet[i].bulletpos,playerpos);//Get distance between player and bullet
+ if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)
+ //If collision is detected or the bullet flys out of screen, delete it.
+ {
+ bullet[i].exist=false;
+ bullet[i].bulletpos.x=bullet[i].bulletpos.y=0;
+ bullet[i].bulletdir.x=bullet[i].bulletdir.y=0;
+ bullet[i].dist=0;
+ bullet[i].bullettype=0;
+ }
+ else
+ {
+ bullet[i].bulletspr->RenderEx(bullet[i].bulletpos.x,bullet[i].bulletpos.y,0,0.5,0);
+ }
+ }
+}
+int CreateTower1(double x,double y,int timer,double bs,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)
+ {
+ return i;
+ }
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=1;
+ tower[i].bulletspeed=bs;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,44,0,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].effect=eff;
+ return i;
+}
+int CreateTower2(double x,double y,int timer,double bs,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)return i;
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=2;
+ tower[i].bulletspeed=bs;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,0,0,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].effect=eff;
+ return i;
+}
+int CreateTower3(double x,double y,int timer,double bs,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)return i;
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=3;
+ tower[i].bulletspeed=bs;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,0,0,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].effect=eff;
+ return i;
+}
+int CreateTower4(double x,double y,int timer,double bs,int yelbrk=0,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)
+ {
+ return i;
+ }
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=4;
+ tower[i].bulletspeed=bs;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,88,44,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].yelbrk=yelbrk;
+ tower[i].effect=eff;
+ return i;
+}
+int CreateTower5(double x,double y,int timer,double bs,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)
+ {
+ return i;
+ }
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=5;
+ tower[i].bulletspeed=bs;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,88,0,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].effect=eff;
+ return i;
+}
+int CreateTower6(double x,double y,int timer,double bs,int redexplo,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)
+ {
+ return i;
+ }
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=6;
+ tower[i].bulletspeed=bs;
+ tower[i].redexplo=redexplo;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,0,44,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].effect=eff;
+ return i;
+}
+int CreateTower7(double x,double y,int timer,double bs,int redexplo,bool eff=false)//This returns the created tower number.
+{
+ int i;
+ if (towcnt==0)
+ towcnt=i=1;
+ else
+ {
+ for (i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist)break;
+ if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)
+ {
+ return i;
+ }
+ }
+ if (i>towcnt)
+ towcnt=i;
+ }
+ tower[i].exist=true;
+ tower[i].towertype=7;
+ tower[i].bulletspeed=bs;
+ tower[i].redexplo=redexplo;
+ tower[i].towertimer=tower[i].curtimer=timer;
+ tower[i].towerpos.x=x,tower[i].towerpos.y=y;
+ tower[i].towerspr=new hgeSprite(SprSheet2,44,44,44,44);
+ tower[i].towerspr->SetHotSpot(22,22);
+ tower[i].towerspr->SetColor(0x80FFFFFF);
+ tower[i].whicnt=whicnt;
+ tower[i].effect=eff;
+ return i;
+}
+void ProcessTower1()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=1)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ tower[i].curtimer=tower[i].towertimer;
+ CreateBullet1(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].effect);
+ }
+ }
+}
+void ProcessTower2()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=2)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ tower[i].curtimer=tower[i].towertimer;
+ for (int j=1;j<=12;++j)
+ CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,j*0.5236+clockrot,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ clockrot+=deltarot;
+ //deltarot+=0.004363322313;
+ deltarot+=deltadelta;
+ }
+ }
+}
+void ProcessTower3()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=3)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ tower[i].curtimer=tower[i].towertimer;
+ if (tower[i].t3t==0)
+ for (int j=1;j<=12;++j)
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,j,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ if (tower[i].t3t==1)
+ {
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,12,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,3,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,6,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,9,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ if (tower[i].t3t==2)
+ {
+ if (rand()%2==0)
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,12,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ else
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,6,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ if (tower[i].t3t==3)
+ {
+ if (rand()%2==0)
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,3,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ else
+ CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,9,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ }
+ }
+}
+void ProcessTower4()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=4)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ tower[i].curtimer=tower[i].towertimer;
+ CreateBullet4(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].yelbrk,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ }
+}
+void ProcessTower5()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=5)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ tower[i].curtimer=tower[i].towertimer;
+ CreateBullet5(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ }
+}
+void ProcessTower6()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=6)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ tower[i].curtimer=tower[i].towertimer;
+ CreateBullet6(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].redexplo,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ }
+}
+void ProcessTower7()
+{
+ for (int i=1;i<=towcnt;++i)
+ {
+ if (!tower[i].exist||tower[i].towertype!=7)continue;
+ tower[i].towerspr->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545);
+ if (DisableAllTower)continue;
+ if (LOWFPS)
+ tower[i].curtimer-=17;
+ else
+ --tower[i].curtimer;
+ if (tower[i].curtimer<=0)
+ {
+ tower[i].curtimer=tower[i].towertimer;
+ CreateBullet7(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].redexplo,tower[i].effect);
+ //hge->Effect_PlayEx(snd,100,(tower[i].towerpos.x-400)/4);
+ }
+ }
+}
diff --git a/archive/blr2/COPYING b/archive/blr2/COPYING new file mode 100644 index 0000000..bf98efc --- /dev/null +++ b/archive/blr2/COPYING @@ -0,0 +1,51 @@ +BLRII itself distributes under the terms of the BSD license. +Varieties of hge-unix and hge included in the source code distribution are still zlib-licensed. +Here's the text of the BSD license and the zlib license. +============================================================================================== +Copyright (c) 2014, Chris Xiong +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of "Chrisoft" nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL CHRIS XIONG 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. +============================================================================================== +Copyright (c) 2003-2008 Relish Games + 2011 Ryan C. Gordon + 2013-2014 Chris Xiong + + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from +the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/archive/blr2/ChangeLog b/archive/blr2/ChangeLog new file mode 100755 index 0000000..cbd158e --- /dev/null +++ b/archive/blr2/ChangeLog @@ -0,0 +1,728 @@ +=================================================================== +Next version: +The final release is just there!! +Todo's: +Bug fixes. +Tests. + +Known bugs: +Blue bullets appearing in Vortex of leaves.//don't know why... + +Wishlist: <-strikethrough +~~Now Playing(Music Room)~~ +~~BLR script virtual machine~~(Now working for BLR3) + +Releases: + +1.0.0-0 (r101) +Fix a bug in the hgeft library, and try git... + +1.0.0-0 (r100) +Rev. 100!!! +This is the final release. +No more major changes will be made. +Further changes of BLR2 will only be bug fixes (BGM addition +excluded). + +Changes: +Fix screenshot excluding the info panel. +Make Lv-2P4 harder (reporter: BLumia). +If it is the first time you start BLR in Windows, resolution in +the options menu will be "?". Fixed now. +Fixed a critical bug in scorec.h. + +Pre-Released versions: + +0.9.9-0 (r99) +Rev. 99! WTF? +THIS IS THE FINAL RELEASE CANDIDATE!!! +Everything is frozen, that means no more new features will be +added and no big changes will be made after this revision. Only +bug fixes will be provided. +//Again, "frozen" is a term borrowed from the Debian project and +//is completely unrelated to Cirno! + +Tweak bullet9, shrink its removal border. +Change Multpo texture, add spawning effect. +Fix stubbed rankings. +Update sprite sheet. +Store assessment total elapsed time in the score file. Score +files from older revisions shouldn't cause any errors but you may +get "Time elapsed 0.00" in highscore details. If you've got any +sort of OCD (Obsessive-compulsive disorder), just remove it. +Document!!! + +0.9.8-0 (r98) +Dear Pre-Release Candidate version(RC-0). + +CLR will collect multiplier +1's in range now. +Multiplier +1's caught by player won't disappear now. +Add/Move background transitions. +Add volume control to options. This make the configuration file +not compatible with older versions. Just delete it! +Modify hge's API so that it can handle real volume and pan values. +Volume value varys from 0 to 1, pan value varys from -1 to 1. +Document... + +0.9.7-0 (r97) +Fix: small semi-coll bullets are collected by clr... +Add Multpo's for Level 7/-1. +Do slight changes to level -1... +Distribute CLRs for level 1~-1. + +0.9.6-0 (r96) +Fix bug that cause you unable to charge if you try to use clr directly +after your clr's used up. +Add Multpo's for Level 3/4/5/6, and level 7 partically. +Fix stupid bug in Level4Part2 and other similiar parts. +Fix several bugs in level 5/6. +Reduce given-away score in level "Sine Wave". It wassssSssss too long! +Fix typo... +Blinking HangUpText *should* be fixed now... + +0.9.5-0 (r95) +Change configuration and score file names. Files with their names +begin with "." may be annoying in Windows though... +If we find a score file during first start up, assume it's valid and +don't overwrite it. +Fix the problem that in-game music won't be resumed when back from pause. +Fix the problem that Multpo's won't be removed if a new game is created. +Fix the problem that the first tip is not shown correctly if the game +is restarted. +(Probably) fixed the problem that the sound is played out of game. +Prevent Multpo's from "escaping". This happens when fps is extremely low... +Adding Multpo for Level2. +Update CanonTechno. + +0.9.2-0 (r94) +Mod, mod, mod...! +Assessment mode is mostly frozen now. +I'll make a pre-release at r99 and that revision will be set to +0.9.9-0. +Write the document... That's really tiring. + +~~0.9.1-4 (r94)~~ +Ooooooooops... I've forgotten to commit this one! +So this is merged to the revision above, actually. +================================================================================= +Modify a couple of levels. (Making them easier...) +Fix about scene text rendering out of the window. +(Probably) fixed Level3Part3 by making them temporarily invulnerable... +Are we bug-free now? + +0.9.1-4 (r93) +Picking it up after almost one month... I'm now lost in my code... +--------------------------------------------------------------------------------- +Add player position display into debug display. +Rewrite pinball, adding collision between the balls... +The collision code is based on Kollision (a game included in KDE SC). + +0.9.1-3 (r92) +I installed Archlinux alongside Debian recently. Now we officially support +Archlinux and Debian. +Archlinux doesn't eat my CPU or try to destroy it... So further development will +be made mainly under archlinux... +--------------------------------------------------------------------------------- +Content freeze -- nothing will be added or removed any more (music etc excluded). +Fix build failure in Archlinux. +Fix font issue in Archlinux. +realloc may change the base address... That's the cause of the crashes... +--now removing all Bullet* based implementations. +Affected parts: +Assessment: Constant patterns, pinball +All parts in level 2. +L4P2, and more +L5P5~6 +L-1P17 +L-1P19 +L3P3 +L7P12 +L7P14 +L7P25 +Avoid memory leaks... I don't know if they have been really fixed... + +0.9.1-2 (r91) +Add built-in help. +Now the pause menu should be fixed... +Compress resources again. + +0.9.1-1 (r90) +Fix a bug in the credit scene. +Now the pause menu shouldn't be broken now...(It's so hard to reproduce +that I have to assume it *has* been fixed.(IT STILL HAPPENS!!!) +Close the "infinity CLR" "bug". +(Huge) Code cleanup, mainly removing duplicate code. +Allocate bullets dynamically. The array is freed every time a new game +is started. +Add a signal handler, print back trace on error(currently only available +for linux...). + +0.9.1-1 (r89) +Fix a critical bug in Score_Initailize. +Modify level pinball. +Drop "_PR" in version string. +Partly rewrite the credit scene, displaying accurate version +details. +Remove some warnings from hgewin. +A set of basic tests are done on a Intel+Nvidia desktop computer. +Add a simple build script(instead of makefile). +Reduce the Windows version executable size...(local work, recompile +freetype using reduced features enabled.) +Current tested (by me) and worked plantforms: +Debian sid x86_64/Windows 8.1 @Intel core i7-2670QM, 8GiB RAM, +Intel HD3000. +Debian sid x86_64 @Intel Core2 Quad Q8300, 8GiB RAM, nvidia GT320. +Windows XP x64 @VirutalBox, Dualcore Virtual CPU, 1.5GiB RAM, VBox +Addons installed. +Windows XP @Intel core i3-3240, 4GiB RAM, Intel HD3000. + +0.9.1-1_PR (r88) +%lld seems to work with mingw-w64(also VS2005+)... +So let's remove all %I64d. +Change point bullet behaviour. +Fix a minor multiplier problem. +Mark the source code as C++. +Re-document levels(not done). +Update wiki. + +0.9.1-1_PR (r87) +Disable screenshot when you're entering your honourable name. It's +not tested so we could only hope that will work... +Add crappy sounds to (part of) the menus. + +Replace a level in assessment mode. The original one was meanless.. +The menu sounds are too crappy... remove them temporarily. However, +let's complete the code base so that we won't waste time writing +it... + +0.9.1-1_PR (r86) +Port highscore view and details menu. Menu rewrite is almost done! +Disable select key while transferring. +Fix "typo" caused bugs. +Hopefully fix small bugs in the new menu system. +Rename several files. Add some additional files. +Remove legacy menu components. + +0.9.1-0_PR (r85) +Port death menu, complete menu and new highscore menu to the new +menu code base. +Clean up old menu code. +Update wiki. + +0.9.1-0_PR (r84) +Port player preference menu, pause menu and return to title menu +to the new menu code base. +Add shake effect to player preference menu. +Make effects faster... +Press esc in a menu will select back/exit now. +Add several background transfers. +Fix possible memory leaks in HangUpText. +Remove some commented statements. + +0.9.1-0_PR (r83) +Now you can change the game resolution. +Some resources are not re-made so they may look blurred... +Make font bigger for higher resolution. +Add command line option for changing the resolution. +Complete the option menu rewrite. + +0.9.1-0_PR (r82) +Add missing file menus.png... +Finish the start menu rewrite. +Modify "Lunatic Lunar", however it's not done... +Modify resource unpacking of Windows version. + +0.9.1-0_PR (r81) +Start menu rewrite... +Add information about the built time. + +0.9.1-0_PR (r80) +Remove "high FPS mode", it won't reach 500 FPS on my computer any +more. Replace it with Vsync mode. +Add float HGE::Timer_GetFPSf(). The return value will be updated +every 1000ms. + +0.9.0-1_PR (b79/r79) +Bump version! +BLR will use revision number instead of build number one day... +==changelog here== +New assessment level "density test"... +New assessment level "pinball"... +New assessment level "Road blocks"... +New assessment level "Extreme speeds"... +New assessment level "Messed up"... +New assessment level "Bonus - Lunatic Lunar!", finishing assessment +mode! +Laser extentions, add LineLaser for two-point laser inheriting all +Laser interfaces. +Modify laser collision parameters. +Level corrections. +Improve density test. +Add screen shot. Press S for a screen shot. +Fix the upside down screen shot output. +Fix stubbed HGE::System_Launch. + +0.9.0-0_PR (b78) +First two assessment levels. +Two more assessment levels... +Tow _more_ assessment levels...... +Another assessment level... +Yet another level for assessment mode... why don't I bump the +version? +Modify player attribute. +Allow bullet to kill itself at a certain point. +Add extborder attribute. +Finish assessment system framework. +Add circ2pnt. + +0.8.1-1_PR (b77) +All parts from level -1 to 7 are completed! +Fixed the crash in the mingw-w64 build. +Switch to mingw-w64 for building Windows version now. +Complete GUI bring back. +Fix a bug appeared after the cross-plantform port(when forked +from BLRI). +Prepare for assessment mode. + +0.8.1-0_PR (b76) +New level "Sink over the horizon". +New level "Gravity vortex". +New level "Double reflective". +Make point bullet additive blending. +Allow bullets to pause before being accelerated. +Modify "Gravity vortex". +Modify "Achromatopsia". (Thanks to my classmate's advice...) +Report build and version in the log file. +Add command line argument support. Use "--help" for usage. +Add freetype support to hge. It's still pretty buggy. (and make +the executable extremely big!) +Add experimental support for cross compiling with mingw-w64. +(Mingw-w64 build *will* be the official build in the future.) +Fix blinking HangUpText. +Fix crashes in mingw-64 build. +Change numeric characters to monospace. +Modify player speed settings. +Beewx still messes up memory... fixed now. +Exit 1 if not terminated correctly. + +0.8.0-1_PR (b75) +New level Supernova. +New level (still unnamed). +Support additive blending bullets(for Supernova). +Add some additional tips. +Move levels to level -1. +Fix blinking of HGE::Gfx_SetTransform in OpenGL. +Fix includes like " #include "../../include/..." " that would +cause errors. +Extend libcgh again. Adding operator ^ and method l(). +Modify clearrange behaviour in level hyper-threading. +Modify the corresponding score bullet. + +0.8.0-0_PR (b74) +New level Achromatopsia. +New level hyper-threading. +Tower8 partly rewritten, dropping tdir. +Fix a small problem in level 2. +Move levels to level -1. <-typo fixed +Modify the semi-coll threshold of laser. +SCEffect_Attatch now take a optional parameter. +Global varibles cleanup. +Fix a bug in bullet8 caused by RandomEngine port. +Rename "Minesweeper"->"Spiky", add noname2pnt. +Add achroma2pnt. + +0.7.3-0_PR (b73) +This is a pre-release version of 0.7.2-2_PR. +This version is released to public for level previewing. +This release contains level 1~7 (while level -1/-2 are still +"imaginary") +Changes: +Compress several png files. +Merge code for Windows. +Fixed compile problems of Windows version. +Small fixes of level2. +This build will be short-lived. + +0.7.2-2_PR (b72) +New level "return to void". That's a 3 in 1 class. I used +particularly many "return(void)(...);" in this level (which I +always love to use). +This indicates all "normal" levels are completed. +Multiplier system was fully adopted into BLR. +Implement a RandomEngine, replacing all rand(). +Rewrite Leaf_Anim using std::list, won't cause crashes now. +Fixed: Trypophobia stops if too many CLR's are used. +Fixed the problem in All2pnt(). +Fixed blinking target. +Fixed Hexagon loops memory leak (the pointer array is too small...) +Tests under Windows were done, all gameplay features ran perfectly. +Make Laser::GetDist() private to avoid misusage. +Fixed several background problems. +Remove unused statements: +DWORD ColTrans(DWORD,DWORD,DWORD): replaced by +DWORD ColorTransfer(DWORD,DWORD). +void SaySomethingAndBye(char*): useless. +void DirectBullet(Bullet&,double): this has been coexisted with +the same method in the Bullet class for a long time. Now it's +replaced by Bullet::setdir(double). +A Small bug in the Windows build is fixed. +File list in the Windows build is updated. + +0.7.2-1_PR (b71) +(Level7 will be almost twice longer than Level6!) +I'm extremely tired these days, I can't even keep my eyes open +while typing... +Some of my classmates helped testing several levels and found +some bugs, thanks a lot! + +After a short test, I found that the Windows build is almost +broken... Crashes and misbehaves are everywhere! + +Maybe Windows is noble and won't run this garbage:( +===Real changelog starts from here=== +New level "Trypophobia", however it seems that this level won't +cause trypophobia at all! +New level "Photon fusion", using a slightly modified Tower8. +Rewrote laser distance detection using vector2d calculations, +extending libcgh and bump its version at the same time.(*2) +Put the new level to the correct place. +Bring back "Minesweeper" level, adjust it to the new interfaces. +Convert Bullet from struct to class. +Bring back Classic Mode. There are no "easy", "normal" or "hard" +now, there's only "classic"! Fix problems with the classic mode in +the new code base. +Fixed a bug appeared after the levels were put together. +Other minor changes to the level WOP. +Minor cleanups and code style adjustments. Add missing free's and +delete's. +Remake the credits page, it grows from 350KiB to 6MiB. (And so I'll +enable PNG compression later.) + +0.7.2-0_PR (b70) +I wasn't willing to bump the build number because I want the svn +revision to chase the build number. +However it wouldn't be appropriate to put three new levels into one +build... +The real changelog is here: +New level "interference" (it's another small class "SimpleThing"). +New level "diffraction" (yet another dull class), hopefully fixed a +memory leak in this level (by using more memory!) +Rearrange levels to the order they will appear in the final version. +New background interface, use background pictures easily. +Make "Tiled" background mode work. +Add SetScale to background class. Make you dizzy easily... +Fix a small glitch in Level3Part3-4. This level won't run correctly +under Low FPS Mode. +Minor code cleanups. +Removed more useless comments, my code is still hard to comprehend, +though. +Fix the misbehave of modulo with minus numbers... +Small interface and behaviour changes: +-If a bullet is effect-attatched and the effect is running, it won't +die. +-Bullet::redir now always make dist=1, for some bullet processing +doesn't use dist now. +Don't copyleft, it's radical. + +0.7.1-6_PR (b69) +Finish some new levels ("Great Circle" bring back & "rainbow +appearance"). +Fusion bullet first work draft. +Fix some of the warnings from the compiler. +Adjust level difficulty. It was indeed too easy... +Remake some resources with GIMP. +Merge great circles and finish it. +Small code cleanups. + +0.7.1-5_PR (b68) +Draft new level. (Another level threatening you using circles!) +Update some old interfaces from BLR1. + +0.7.1-4_PR (b67) +New level (name and placement undetermined). +Fix level transition mismatches. +Improved accelerated bullets. + +0.7.1-3_PR (b66) +Fix a few glitches. Removing some useless interfaces for BLR I. +Change "Dangerous Target" for proper difficulty. + +0.7.1-2_PR (b65) +Bullet death effect, applied to Wave of Photon. It seems buggy. +Fixed something left for debuging in the last commit. + +0.7.1-1_PR (b64) +New level: Wave of Photon. A lazy level again. Despite of a new +class, it's a copy of "photon school". +Level improved: Cross threaten. Make it impossible to pass this +part without crossing those blue bullets. +libcgh improvement. Added new interfaces to vector2d struct. So the +libcgh version was bumped. Was it worth doing that? + +0.7.1-0_PR (b63) +New level: Rainbow bullets - nauty photon (in fact it's a lazy +level! I must have seen the same thing some where else...) +The last "photon school" level was put to where it should be. +Rewrite some silly parts of the Changelog. +I ran out of my AppEngine quota today... So I can't commit that to +svn as planned... + +0.7.0-9_PR (b62) +Performed a couple of tests, under both full FPS mode and low FPS +mode. +New background is used by now. + +0.7.0-8_PR (b61) +Improved the rendering code. More tests are required... +That made the rendering more efficient. It also eats less RAM then. +--Okay it's now tested. Another bug in FPS independent bullets +fixed. No (big) bugs were found in the new rendering code. + +0.7.0-7_PR (b60) +Spring Festival commit... +One level is rewritten. +Ready to sync this to svn... + +0.7.0-6_PR (b59) +Fixed 3D clouds background. New background components added. +Experimental FPS independent bullets. + +0.7.0-5_PR (b58) +Fixed another critical bug in laser collision detection +implementation... Laser is almost perfect now...//Still, it's +inefficient. + +0.7.0-4_PR (b57) +Fixed a critical bug in laser implementation and another awful +memory leak bug... + +0.7.0-3_PR (b56) +A new level is going to be complete... + +0.7.0-2_PR (b55) +Auto pause and do not make game suspend if focus is lost. + +0.7.0-1_PR (b54) +First two parts for level7. + +0.7.0-0_PR (b53) +New background for level7. Preparing interfaces for level7. + +0.6.2-2_PR (b52) +Level6 is frozen now. It's the longest level ever... (in blr!) + +0.6.2-1_PR (b51) +Completing level6! +Spring is coming? (Well, not really...) + +0.6.2-0_PR (b50) +Completing && improving hexagon. +Bumped the minor version for the sixth level is almost complete. + +0.6.1-4_PR (b49) +New level hexagon. + +0.6.1-3_PR (b48) +New level...(Avalanche) +Spotlight: Supporting BGM loop points(using my new hge +interfaces...)! +I have no idea on new levels (except "hyper fluid", that's a well- +planned part...). Maybe I've spent too much time staring at the +desktop? I feel like void these days. +The build count is bumped four times a day, you enough! + +0.6.1-2_PR (b47) +New level "Wriggle Nightbug-like"?... + +0.6.1-1_PR (b46) +Implemented several unimplemented audio interfaces of hge (OpenAL). +A Windows build to check compatibility is planned. + +0.6.1-0_PR (b45) +Now we have 11 parts in level6... +A BGM called Canon Techno is completed around here... + +0.6.0-0_PR (b44) +Starting level 6! +//We are in 2014 now. I'm regretful for I didn't have the dates +recorded. + +0.5.3-2_PR (b43) +Optimizing memory usage... (first step...)[*] +Borrowed "the unbreakable jail" from old code... +//[*]Note @ 0.6.1-3 && @ 0.7.0-9: +//1. I found this useless. +//2. This may cause SIGSEGV! +//3. It's completely removed after b61. Because they are not used +// any longer + +0.5.3-1_PR (b42) +Final(the second last..) level for level 5, fish in a barrel? + +0.5.3-0_PR (b41) +Small fixes and levels as usual... + +0.5.2-3_PR (b40) +New minor parts for level5, fixed a bug in Player_Clear_Rotate. + +0.5.2-2_PR (b39) +Several patches on new clear range. +Changing interfaces for new levels. + +0.5.2-1_PR (b38) +New trigger method for clear range... + +0.4.4-0_PRG (b37a) +Regression version for releasing... +------------------------------------------------------------- +This will be released as a official Preview Release version.<-obsolete +------------------------------------------------------------- + +0.5.2-0_PR (b37) +New part for level5. Now I'm working on the regression 0.4.x. + +0.5.1-1_PR (b36) +Several fixes including: +-Fading info panel when approaching. +-Sending mult. inc. indicator layer up. + +0.5.1-0_PR (b35) +First two levels of level5. + +0.5.0-0_PR (b34) +Starting level5... Crazy Autumn... + +A regression is planned to release a 0.4.x-x_PR version as +official pre-released version. However it's still nowhere in sight +that if I could use Windows these days. + +0.4.3-0_PR (b33) +Level4 is almost complete. Now I'm using LOW FPS Mode for +development because I just want to cool my laptop down without +using my own power. //However I stopped that at the next version... + +0.4.2-0_PR (b32) +A new level... without using *ANY* old code (from level.h). + +0.4.1-2_PR (b31) +Level4 is now 18 parts... + +0.4.1-1_PR (b30) +Transfered sevel old levels here. + +0.4.1-0_PR (b29) +Optimizing old code for level4. + +0.4.0-0_PR (b28) +Now let's move to level4... + +0.3.2-0_PR (b27) +New levels for level3. In fact, it's almost completed now... + +0.3.1-2_PR (b26) +Improved bullet clearing method, avoiding hidden bullets +completely!(Just by converting them all to score points...) + +0.3.1-1_PR (b25) +A new "big" level for level3. +Added several new interfaces to tower&bullet section. + +0.3.1-0_PR (b24) +Complete the first two parts of level3. + +0.3.0-0_PR (b23) +Starting the development of level3... + +0.2.9-2_PR (b22) +Completing level2... + +0.2.9-1_PR (b21) +New parts for level2. level2 is almost completed now. +PlayerLockX/Y implemented. +------------------------------------------------------------- +This will be released as a official Preview Release version.<-obsolete +------------------------------------------------------------- +BLR will be licensed under WTFPL from now. +(WTF?) +............................................................. +No it's now licensed under the BSD license... + +0.2.9_PR (b20) +Level 2 is frozen "by heart". (How? By heart?) + +0.2.5_PR (b19) +Optimizing the second level to a "realistic" state... Added two +extra musics(although still remain not used). + +0.2.2_PR (b18) +The main development has been transferred to Linux. Optimizing +code for Linux. +//Revision count is not important. + +0.2.0_PR (b17) +Level 2?... + +0.1.7-2_PR (b16) +The first level is almost completed now... + +0.1.7-1_PR (b15) +Fixed several serious bug in Low FPS Mode. Fixed FPS Level option +code. + +0.1.7_PR (b14) +Updated the only level to synchronize with the In-Game Music. +Added "Multiplier +1" into the game system. Added an unimportant +loading screen.//In fact, it's loading nothing. May be unpacking +resource pack in Windows version... + +0.1.4_PR (b13) +libcghEx has been made independent and can apply to any other +projects. This is also the first BLR version that includes +In-Game Music. libcghEx has been extended with LinearProgresser +and HangUpText. + +0.1.1_PR (b12) +Added auto-multiplier system. libcghEx (Chrisoft Game Helper +Extras Library) is included in this version with CircleIndicator. + +0.1.0_PR (b11) +Creation of the Pre-Released Version. Removed all old level code. +Bourne-again!//Can you imagine what I was thinking when deleting +the result of 3 months' work?... +================================================================= +TestBed versions: + +TB130907 (b10) +A "Noname" level. Laser implementation partly rewritten. + +TB130903 (b9) +Additional backgrounds + +TB130827 (b8) +Laser implementation, Cheers! + +TB130818 (b7) +New Levels such as rainbow towers and squashing levels. + +TB130802 (b6) +Discarding old code, rewrite of part of the code. + +TB130718 (b5) +Bullet creation effects, sync code back to BLR1. + +TB130714 (b4) +Target indicator completed. + +TB130705 (b3) +New level and bullet creation code for orange bullets. + +TB130703 (b2) +Completing Orange Towers. + +TB130620 (b1) +Completing Deep Blue Towers.//Well, "Dark Blue" right? Or more formally, "Navy". +//However, they are all not the real color. I used #0000FF, which is just "Blue", +//it just seems dark. + +TB130610 (b0) +Creation of Testbed version. diff --git a/archive/blr2/Extras b/archive/blr2/Extras new file mode 100644 index 0000000..0368e7e --- /dev/null +++ b/archive/blr2/Extras @@ -0,0 +1,133 @@ +BulletLabRemix II, Extras +2014-06-06 + +Content +------------------------------------------------------------------------------------ +About the source code +About resources used in the game +The development + +About the source code +------------------------------------------------------------------------------------ +I'm not a rigorous coder. All sources are written casually. +You can even find two code chunks in one file with different styles... +But generally, I: + Use tabs (width=4) and indent in Allman style; + Don't like extra spaces; + Prefer commas if possible; + Don't like very long names. + +And, the source code is bloated. global.h defined ~200 lines of global variables. +Imagine that. + +Well, the reason is that BLRI start as a huge monolithic source file - main.cpp. +It's once a ~100KiB file, and have more than 10k lines of code. One day I found it +impossible to maintain such code and split it into several .h file. BLRII took the +code base of BLRI. That's why. BLRIII will be a complete rewrite and I hope this +would fix the problem. + +Well, let's observe each source file. + +background.h Defines and implies background animation. +effects.h implement several simple in-game effects. +global.h Defines global variables and routines. +hgeft.h Free type interface for HGE. It's considered buggy and + incomplete now... +levels.h implement the levels. +libcgh.h Chris' Game Helper interfaces. +loading.h Resources for the loading screen. +menus.h implement the menus. +music.h Music playback and looping. +scorec.h Record highscores. +scoresystem.h The BLR Multiplier scoring system. +towernbullet.h implement towers and bullets. +hgeft.cpp Free type interface for HGE. This is the implementation. +libcghEx.cpp Extra routines for the CGH. +main.cpp Contains main(int,char**), and player controls. + +About resources used in the game +------------------------------------------------------------------------------------ +Most resources are self-made... + +b_diff.png A café wall illusion background +b_inter.png A swirl illusion background +b_leaves.png Taken from a Windows 3.1 desktop background, unused +b_null.png Simple white background +blnsns.png Font file. Font name "Berlin sans" +credits.png Resources used in the credits screen. +e_leaf.png Texture for leaves background effect. Taken from a Windows 3.1 + dekstop background. +e_sflake.png A snow texture for background effect. Taken from public domain. +e_skyitem.png Sky background resources. Taken from HGE tutorial. Cloud is + from public domain. +help.png Built-in help. +menus.png Menu textures. +ss.png Sprite Sheet. Taken from BLRI. Made with inkscape. +title.png Title sprite. Pre-processed with inkscape. +All resources are processed or made with GIMP. + +menuin.ogg Menu effect. Made with OpenMPT. +menuout.ogg Ditto. +tap.ogg Widely used. Taken frome HGE. + +BLR2_TR01.ogg Background music for level1. Original by Noby. +BLR2_TR07.ogg Background music for level7. Original by Chris Jarvis. +BLR2_TR09.ogg Background music for credits scene. Taken frome BLR2_TR07. +CanonTechno.ogg Bonus? Made by Chris Xiong. +Softwares used: OpenMPT, Rosegarden, Cakewalk Sonar 6. +Syntheis: QSynth+Fluid R3 sf, Roland Groove Synth, Cakewalk TTS-1, Roland +Super Quartet. +Proprietary softwares are all cracked. I can't afford them now. + +The development +------------------------------------------------------------------------------------ +As a student, developing such a game will never be supported... +So, the development is "well hidden". +The post-0.2.2 development are mostly done under Windows(8/8.1). After that, I +migrated the main platform to Debian GNU/Linux. I'm using the unstable distribution. +I'm not a true developer but I'm really one of those who like to like on the edge. +Recently I installed Archlinux, which has taken me to the "bleeding edge". "Edges" +are different from "borders", they are more sharp! + +Well, I first played BulletLAB when I was 13. It's easy enough and I passed the easy +levels without any trouble. Then I tried normal and hard, all done without much +difficulty. Then comes the "Extreme" mode, in which you have to pass the whole game +without misses. That took me a long time... + +In March 2013, I was pretty bored (in fact, preparing a contest). And I found the +small flash game again. I decompiled it, and started modifing it. Soon I found this +interesting, and made the game VERY difficult. I even "released" that. + +However, flash is really inefficient. As the bullet number grows, FPS falls +violently. So a rewrite is planned. + +First things first, how to draw so many objects on a screen? An STG game that has a +file "hge.dll" in its directory came to my mind. I could still see the fancy effects +it has. I googled for hge and found that it's a hardware accelerated game engine. + +Well, that's it! I wrote several simple scenes as practices, then BLRI started. I +found HGE really powerful and can draw 2000 objects in 1000FPS. F***in' awesome! + +BLRI's source code growed rapidly. Soon it's almost 100KiB. It's almost impossible +for me to maintain so big a file. That's why the source code is presented in many +headers. + +When BLRI reached 0.8.6, BLRII was forked from it. BLRII started as a level testbed +for BLRI. However, BLRI was frozen (this term is borrowed from the debian project, and +is not at all releated to Cirno) before these levels can be added to it. If they +*were* added, the source code of BLRI would no longer be human-readable. + +As BLRI was released (as 1.0.3SR), I can relax myself a bit. During that I found +hge-unix, which can port almost any hge-based game to UNIX. I tried it and it works! + +Then I started modifing hge: migrating the Windows version to DirectX 9, implement +stubbed functions in hge-unix, deprecating libbass and migrating to OpenAL... + +Soon I completed them all. Then I picked up BLRII (around Oct. 2013), which already +has free-shaped lasers implemented. + +To declare my ambition to change BLR, the whole level.h was removed (with a backup +of course). + +However this didn't change too much. Almost all levels were ported back to the +current version later.
\ No newline at end of file diff --git a/archive/blr2/FAQ b/archive/blr2/FAQ new file mode 100644 index 0000000..9935458 --- /dev/null +++ b/archive/blr2/FAQ @@ -0,0 +1,168 @@ +===Under Construction=== +In fact, these Q&A's are not asked frequently at all. +They all came from the messed up mind of the author! + +Q: It complains about a missing dll? +A: The Windows version was built against d3dx9_43.dll, which can + only be found in the latest DirectX runtime. Make sure you have the + latest DirectX runtime installed. + Other dlls required by the default Windows version are all bundled + with your Windows installation plus the DirectX runtime. You + shouldn't blame me if your system is incomplete. + +Q: I JUST CAN'T start it! (I can't see even a window!) +A: Something must went wrong. There are two general causes. + 1. Failed to load a shared library. + 2. Initialization Failure. + If the first one happened, BLRLOG.TXT will not even be created. + To solve it, install the required runtime libs. + If the second one happened, you can find out what really happened in + BLRLOG.txt. Read the rest part of this document for more information. + + However, the first one is not likely to happen. The official Windows + build doesn't have too much external dependencies. + +Q: (In Windows) + "Can't create D3D interface" + "Can't determine desktop video mode" + "Can't find appropriate full screen video mode" + "Can't create D3D device" + and it ends after this... +A: DirectX initialization failed. + If you get this message after changing an option, the cause might + be your option is not supported by your computer. You can purge + the config file (back up your score and remove .blrrc) and + restart the game. + If you get this message on the first startup, you are just unlucky. + HGE, which is the render engine used in BLR is really low-ended + and will even work on a 1998's computer. Again, you are just unlucky! + +Q: (In linux or custom Windows builds) + "OpenGL implementation must be at least version 1.2" +A: If you build a custom Windows build with OpenGL, this may occur, for + Windows' OpenGL implementation is 1.1. For a work around, see the + SDL website or build the DirectX version. + If this happens in a Linux build, you are just unlucky. OpenGL 1.2 + is released in 1998... + Similiar problems may also happens if your X display is not a GL visual + or you haven't installed drivers properly. + It's also possible that you are using OpenGL Soft, which is not + supported. + +Q: "******** failed, using no sound", and it's silent... +A: OpenAL initialization failed. + Your system may not support OpenAL software version (it's so hard to + find such a computer). To dismiss this message, start the game with + "--nosound". + +Q: The screen suddenly messed up... + Something terrible happened... + Is the player square screwed? + I can't move it! +A: This might be a internal problem. Please make a bug report if this + happened. + +Q: It crashed! +A: This program may crash at any time. + If it crashed, you can post your problem with BLRLOG.txt attatched + to google code issue tracker. I'll try to fix the problem if I can + reproduce it. + +Q: "Cannot decompress resources!" (Windows only) +A: I've compressed the resources of the game for Windows. As the game + starts, it will create two folders and decompress the resources + into them. If that failed, this problem will be reported. + Restarting the game may solve the problem. If it still fails, check + if expand.exe exists in your system(It's an essential system file!). + +Q: Your code cannot compile! +A: I'm pretty sure that it CAN compile(on my machine). + Check if you have all required sdks installed and if you have + configured the project correctly. + Additionally, if you checked out an older revision from svn, I + cannot guarantee that it can compile! + +Q: What are BLRData.dtp and BLRMusic.dtp? +A: As the name tells, these are archives containing the game data. + You can decompress them with expand.exe (which may be found in + the mystery folder "system32"). + +Q: It's blurred? +A: The game was designed for 800x600, and if you are using a resolution + other than 800x600 or running in fullscreen, this problem may occur. + +Q: I can't see the bullets when paused? +A: That depends on the implementation of the level where you are. + Some levels are implemented using the silly "SimpleBullet" class + which I once think it brilliant. These bullets won't be displayed + during the pause. + Pause menu was not introduced in BLR I until version 0.8.9 alpha. + The reason was I thought a menu for the pause scene was really + useless... + BTW, if you've ever played the official version of the Touhou series, + you might have found the pause scene there more annoying. The author + has stated that he made it deliberately (see TH06 FAQ 25). + +Q: I don't think the graphics are being rendered correctly. +A: I don't know much about DirectX, for I left hge DirectX untouched. + However it shouldn't differ too much from the OpenGL version. + All quads are rendered as triangles, and uses vertex buffer. + Maybe there are "graphics driver dependent" contents, I'll correct them + later. + +Q: It's sssSssso hard! +A: It's supposed to be hard! The only solution is to practice more. + However you can get more CLRs in player preference settings (with + a sacrifice of moving speed). + +Q: I can't get those "+1"'s... +A: It's designed to be so! Some of the "+1"'s are only for adventurers! + +Q: Tell me the history. +A: Changelog tracked a full history of this project (Although it's not + detailed). + By the way, this project started as a fork of BLR I, which is already + closed by me now. + +Q: Are there command line options? +A: Yes. It's documented in README.txt. + BTW, --start and --fast came up for debug purpose only. + However they are a hidden bonus for cheaters. + So, I won't remove that in the final version. I promise. + (P.S.: misusage of --start may cause severe problems!) + +Q: Rankings of this game? +A: If you can reach level 1~3... + --You are not suitable playing this sort of game. + If you can reach level 4~6... + --You are a normal human-being. + If you can pass level 6 or reach level 7... + --You are unusual. + If you can pass level 7... + --Are you "nobody"? + If you can pass level -1... + --Tell me the reason why you come to Earth... + +Q: Why can't I play all levels, it tells me "It Ends Here"! Do I have to pay + you for it? +A: Of course not! 'Cause You just restarted too many times or had too many + collisions. The detailed requirements is listed below. + Level Restarts allowed Collisions allowed + level 2 N/A N/A + level 3 1 10 + level 4 2 40 + level 5 3 75 + level 6 5 125 + level 7 8 200 + level -1 2 50 + + For example, to enter level 6 you can restart 5 times at most (classical + mode), or have 125 collisions at most (FreePlay Mode). + + Level -2 can only be accessed in assessment mode or "--start" option. + +Q: Are there other awards? +A: Sorry, no... + You won't get anything but the ranking even you've passed level -1 without + collisions. + So... enjoy it yourself. diff --git a/archive/blr2/FAQ.zh b/archive/blr2/FAQ.zh new file mode 100644 index 0000000..f6561f5 --- /dev/null +++ b/archive/blr2/FAQ.zh @@ -0,0 +1,141 @@ +===建设ä¸=== +In fact, these Q&A's are not asked frequently at all. +They all came from the messed up mind of the author! + +Q: 它说缺少什么dll? +A: Windows版本是ä¾èµ–d3dx9_43.dllçš„ã€‚ä½ åªèƒ½åœ¨æœ€æ–°çš„DirectX库ä¸æ‰¾åˆ°å®ƒã€‚ + æ‰€ä»¥ç¡®è®¤ä½ æ˜¯å¦å·²ç»å®‰è£…了最新版的DirectXè¿è¡Œåº“。 + 其他所有需è¦çš„dll都是Windows/DirectXè¿è¡Œåº“è‡ªå¸¦çš„ã€‚å¦‚æžœä½ çš„ç³»ç»Ÿä¸å®Œæ•´ï¼Œ + å°±ä¸è¦æ¥æ‰¾æˆ‘了… + +Q: 我就是ä¸èƒ½å¯åŠ¨å®ƒï¼(我连个窗å£éƒ½çœ‹ä¸è§ï¼) +A: ä¸€å®šæœ‰ä»€ä¹ˆä¸œè¥¿å‡ºé”™äº†ã€‚å¤§çº¦æ˜¯ä»¥ä¸‹ä¸¤ä¸ªåŽŸå› ä¸çš„一个: + 1. æ— æ³•åŠ è½½æŸä¸ªå…±äº«åº“。 + 2. åˆå§‹åŒ–失败。 + 如果å‘生的情况是第一ç§ï¼Œé‚£ä¹ˆBLRLOG.txt甚至都ä¸ä¼šè¢«åˆ›å»ºã€‚ + 解决方法是安装所需的è¿è¡Œåº“。 + 如果第二ç§å‘ç”Ÿäº†ï¼Œä½ å¯ä»¥ä»ŽBLRLOG.txtä¸çœ‹åˆ°åˆ°åº•æ˜¯ä»€ä¹ˆå‡ºäº†é—®é¢˜ã€‚ + + ä¸è¿‡ï¼Œç¬¬ä¸€ç§æƒ…况å‘生的å¯èƒ½æ€§éžå¸¸å°ã€‚å‘布的Windows版没有那么多外部ä¾èµ–。 + +Q: (Windowsä¸) + "Can't create D3D interface" + "Can't determine desktop video mode" + "Can't find appropriate full screen video mode" + "Can't create D3D device" + 然åŽå°±ä»€ä¹ˆéƒ½æ²¡æœ‰äº†... +A: DirectX没能æ£å¸¸åˆå§‹åŒ–。 + å¦‚æžœä½ åœ¨ä¿®æ”¹äº†ä¸€ä¸ªè®¾ç½®ä¹‹åŽå‡ºçŽ°äº†è¿™æ ·çš„é—®é¢˜ï¼ŒåŽŸå› å¯èƒ½æ˜¯ä½ 的电脑ä¸æ”¯æŒè¿™ç§è®¾ç½®ã€‚ + ä½ å¯ä»¥æ¸…除é…ç½®æ–‡ä»¶ï¼ˆå¤‡ä»½ä½ çš„åˆ†æ•°æ–‡ä»¶ï¼Œç„¶åŽåˆ 除BLR.cfg)然åŽé‡æ–°å¯åŠ¨æ¸¸æˆã€‚ + 如果第一次å¯åŠ¨å°±å‡ºçŽ°äº†è¿™ç§æƒ…å†µï¼Œé‚£å°±æ˜¯ä½ å¤ªä¸å¹¸äº†ã€‚BLR的渲染引擎(hge)在1998 + 年的电脑都å¯ä»¥æ£å¸¸å·¥ä½œã€‚é‡å¤ä¸€éï¼Œä½ è¿˜æ˜¯å¤ªä¸å¹¸äº†â€¦ + +Q: (linux或者éžå®˜æ–¹çš„Windows版本ä¸) + "OpenGL implementation must be at least version 1.2" +A: å¦‚æžœä½ è‡ªå·±ç¼–è¯‘äº†ä¸€ä¸ªä½¿ç”¨OpenGLçš„Windows版,就有å¯èƒ½å‘生这ç§æƒ…å†µã€‚å› ä¸ºWindowsçš„ + OpenGL版本是1.1的。为了获å–ä¸€ä¸ªè§£å†³åŠžæ³•ï¼Œä½ å¯ä»¥çœ‹çœ‹SDL的官网或者编译一个使用 + DirectX的版本。 + 如果这å‘生在Linuxç‰ˆä¸Šï¼Œä½ è¿˜æ˜¯å¤ªä¸å¹¸äº†ã€‚OpenGL 1.2是1998å¹´å‘å¸ƒçš„æ ‡å‡†â€¦ + ä¸è¿‡å¦‚æžœä½ çš„X display没打开OpenGL支æŒï¼Œæˆ–者没有æ£ç¡®åœ°å®‰è£…驱动,该问题å¯èƒ½ä¹Ÿä¼šå‘生。 + å¦æœ‰ä¸€ç§å¯èƒ½ï¼Œå°±æ˜¯ä½ æ£åœ¨ä½¿ç”¨OpenGL Soft,而本游æˆä¸æ”¯æŒå®ƒã€‚ + +Q: "******** failed, using no sound",然åŽä»€ä¹ˆå£°éŸ³éƒ½æ²¡æœ‰â€¦ +A: OpenALåˆå§‹åŒ–失败了。 + ä½ çš„ç³»ç»Ÿå¯èƒ½ä¸æ”¯æŒOpenAL软件版(找到这么一å°ç”µè„‘是何其的ä¸å®¹æ˜“啊)。 + å¦‚æžœä½ ä»¥åŽä¸æƒ³å†çœ‹åˆ°è¿™æ¡æ¶ˆæ¯ï¼Œå¯ä»¥å¸¦"--nosound"å‚æ•°å¯åŠ¨æ¸¸æˆã€‚ + +Q: å±å¹•çªç„¶èŠ±äº†ï¼ + å‘生了å¯æ€•çš„事情… + 那个方å—被åƒæŽ‰äº†å—? + æˆ‘æ²¡æ³•ç§»åŠ¨å®ƒï¼ +A: è¿™åº”è¯¥æ˜¯ä¸ªå†…éƒ¨é—®é¢˜ã€‚å¦‚æžœä½ é‡åˆ°äº†è¯·æ±‡æŠ¥è¿™ä¸ªbug. + +Q: å®ƒå´©æºƒäº†ï¼ +A: 这个程åº*éšæ—¶*都å¯èƒ½å´©æºƒã€‚ + å¦‚æžœå®ƒå´©æºƒäº†ï¼Œä½ å¯ä»¥å°†ä½ 的问题附上BLRLOG.txt一起å‘到google code的问题 + 跟踪(大致就是一个类似bugzilla的东西?)上。如果我能é‡æ–°åˆ¶é€ å‡ºè¿™ä¸ªé—®é¢˜ï¼Œæˆ‘å°†ä¼šåœ¨ä»¥åŽ + 试ç€åŽ»ä¿®æ£å®ƒã€‚ + +Q: "Cannot decompress resources!" (ä»…é™Windows) +A: 我将Windows版的游æˆèµ„æºåŽ‹ç¼©äº†ã€‚当游æˆå¯åŠ¨æ—¶ï¼Œå®ƒä¼šå»ºç«‹ä¸¤ä¸ªæ–‡ä»¶å¤¹å¹¶å°†æ•°æ® + 解压在其ä¸ã€‚如果这失败了,将会弹出这个错误框。 + é‡å¯æ¸¸æˆå¤§æ¦‚就能解决了。如果还ä¸è¡Œï¼Œè¯·æ£€æŸ¥ä½ 的系统ä¸æ˜¯å¦åŒ…å«expand.exe(这是个é‡è¦çš„ + 系统文件ï¼ï¼‰ã€‚ + +Q: ä½ çš„ä»£ç æ²¡æ³•ç¼–è¯‘ï¼ +A: 我éžå¸¸è‚¯å®šå®ƒï¼ˆåœ¨æˆ‘的机器上)*能*编译。 + æ£€æŸ¥ä½ æ˜¯ä¸æ˜¯å·²ç»èŽ·å–了所有需è¦çš„SDK,并且工程设置的是å¦æ£ç¡®ã€‚ + å¦å¤–ï¼Œå¦‚æžœä½ ä½¿ç”¨çš„æ˜¯ä¸€ä¸ªä»Žsvn获å–的较è€çš„版本,我就ä¸èƒ½ä¿è¯å®ƒèƒ½ç¼–译了… + +Q: BLRData.dtpå’ŒBLRMusic.dtp是什么? +A: æ£å¦‚åå—说的,他们包å«äº†æ¸¸æˆçš„æ•°æ®ã€‚ + ä½ å¯ä»¥ç”¨expand.exe解压这两个文件,expand.exeå¯ä»¥ä»Žç¥žç§˜çš„system32文件夹 + 下找到。 + +Q: 看起æ¥å¾ˆæ¨¡ç³Šï¼Ÿ +A: 这个游æˆæ˜¯ä¸º800x600åˆ†è¾¨çŽ‡è®¾è®¡çš„ã€‚å¦‚æžœä½ åœ¨ç”¨å…¶ä»–çš„åˆ†è¾¨çŽ‡æˆ–è€…ä»¥å…¨å±è¿è¡Œå®ƒï¼Œ + å¯èƒ½ä¼šå‡ºçŽ°è¿™ä¸ªé—®é¢˜ã€‚ + +Q: æš‚åœçš„时候看ä¸åˆ°å弹? +A: è¿™å¾—çœ‹ä½ æš‚åœçš„时候所在的关的实现方å¼ã€‚有些关是用“SimpleBulletâ€ç±»æ¥å†™çš„。 + 这些å弹在暂åœæ—¶æ— 法显示。 + æš‚åœåŠŸèƒ½ç›´åˆ°BLR Içš„0.8.9 alphaæ‰å‡ºçŽ°ã€‚åŽŸå› æ˜¯æˆ‘ä¹‹å‰è®¤ä¸ºæš‚åœèœå•æ²¡æœ‰ç”¨â€¦ + é¡ºä¾¿ï¼Œå¦‚æžœä½ çŽ©è¿‡ä¸œæ–¹ç³»åˆ—çš„æ¸¸æˆçš„è¯ï¼Œä½ 会å‘现那里的暂åœç•Œé¢æ›´åŠ 烦人。ä¸è¿‡å®ƒçš„作者 + å·²ç»è¯´æ˜Žè¿™æ˜¯æ•…æ„的了(è§TH06çš„FAQ 25)。 + +Q: 怎么这么难啊。 +A: 这是故æ„çš„ï¼å”¯ä¸€çš„解决方法是多练… + ä½†æ˜¯ä½ åœ¨æ¸¸æˆè®¾ç½®ä¸å¯ä»¥æžåˆ°æ›´å¤šçš„CLR(需è¦ä»¥é™ä½Žç§»åŠ¨é€Ÿåº¦ä¸ºä»£ä»·ï¼‰ã€‚ + +Q: æˆ‘æ ¹æœ¬æ‹¿ä¸åˆ°é‚£äº›â€œ+1â€! +A: 这也是故æ„çš„ï¼ä¸€éƒ¨åˆ†â€œ+1â€æ˜¯ä¸“门为愿æ„为它们冒险的人设计的。 + +Q: 我认为图形绘制的有问题。 +A: 对于DirectX,我了解的ä¸å¤ªå¤šï¼Œå› 为我没有修改hgeçš„DirectX版。 + 但是它ä¸åº”该和OpenGL版有太大的ä¸åŒã€‚ + 四边形都是使用顶点缓冲用三角形绘制的。(好åƒçŽ°åœ¨æ‰€æœ‰æ˜¾å¡éƒ½æ”¯æŒé¡¶ç‚¹ç¼“冲?) + 或许还有些跟显å¡é©±åŠ¨æœ‰å…³çš„问题,我将会在以åŽä¿®æ£å®ƒä»¬ã€‚ + +Q: 请告诉我历å²ã€‚。。 +A: Changelog里é¢è®°å½•äº†è¿™ä¸ªé¡¹ç›®çš„整个历å²ï¼ˆè™½ç„¶ä¸æ˜¯å¾ˆå®Œæ•´ï¼‰ã€‚ + 顺带一说,这个工程起åˆåªæ˜¯BLR I的一个fork(),而BLR I现在已ç»å®Œå·¥äº†ã€‚ + +Q: 有命令行选项å—? +A: 有,在README.txtä¸æœ‰å…¶è¯´æ˜Žã€‚ + 顺便,--startå’Œ--fast选项一开始是为调试而设置的。 + 但是它们也是作弊者的一个éšè—ç¦åˆ©â€¦ + 所以,我在最终版ä¸ä¸ä¼šç§»é™¤å®ƒã€‚我ä¿è¯ä¸ä¼šï¼ˆï¼Ÿï¼‰ã€‚ + (错误地使用--startå¯èƒ½ä¼šå¯¼è‡´ä¸¥é‡é—®é¢˜ï¼ï¼‰ + +Q: ç‰çº§ï¼Ÿ +A: å¦‚æžœä½ èƒ½åˆ°Level 1~3... + --ä½ ä¸é€‚åˆçŽ©è¿™ç§æ¸¸æˆã€‚ + å¦‚æžœä½ èƒ½åˆ°Level 4~6... + --一般的水平。 + å¦‚æžœä½ èƒ½é€šè¿‡Level 6或者玩到Level 7... + --ä½ ä¸å¤ªä¸€èˆ¬å•Šâ€¦ + å¦‚æžœä½ èƒ½é€šè¿‡Level 7... + --ä½ æ˜¯â€œæ²¡æœ‰äººâ€å—? + å¦‚æžœä½ èƒ½é€šè¿‡Level -1... + --å‘Šè¯‰æˆ‘ä½ æ¥åœ°çƒçš„目的… + +Q: 为什么我玩ä¸äº†æ‰€æœ‰çš„å…³å¡â€¦å®ƒå‘Šè¯‰æˆ‘“It Ends Here!â€ï¼ˆåˆ°æ¤ç»“æŸäº†ï¼ï¼‰ã€‚ + 我难é“还需è¦ä»˜é’±å—? +A: 当然ä¸ï¼è¿˜æ˜¯å› 为技术太渣了。关于进入下一关的è¦æ±‚,è§ä¸‹è¡¨ã€‚ + å…³å¡ æœ€å¤šé‡å¼€æ•° 最多撞弹数 + level 2 N/A N/A + level 3 1 10 + level 4 2 40 + level 5 3 75 + level 6 5 125 + level 7 8 200 + level -1 2 50 + 举个例å,为了能够进入第6å…³ä½ æœ€å¤šé‡å¼€5次(“ç»å…¸â€æ¨¡å¼ä¸ï¼‰ï¼Œæˆ–者最多撞弹 + 125次(自由模å¼ä¸ï¼‰ã€‚ + + Level -2åªèƒ½é€šè¿‡è¯„估模å¼æˆ–者"--start"选项玩到。 + +Q: 有其他奖励å—? +A: 对ä¸èµ·ï¼Œæ²¡æœ‰â€¦ + å³ä½¿ä½ 一个没有åƒåˆ°ä¸€ä¸ªå弹地通了Level -1ä½ ä¹Ÿä¸ä¼šå¾—到任何东西。 + 所以…自娱自ä¹å§ã€‚ diff --git a/archive/blr2/INSTALL b/archive/blr2/INSTALL new file mode 100644 index 0000000..c48e870 --- /dev/null +++ b/archive/blr2/INSTALL @@ -0,0 +1,29 @@ +Installing a game is really useless, isn't it? +So just compile it! + +A brief guide for compiling BLR +Required SDKs: +OpenAL +ogg +vorbis +DirectX(Windows only) +OpenGL(Linux only) +SDL(Linux only) + +Steps to do: +1. Get the source code. + You can choose from svn or the official packaged release. + The code from svn will always be newer than the official + packaged release. +2. Get required SDKs mentioned above. + Piece of cake. +3. Use Visual Studio(Windows) or Code::Blocks(Linux), create + project. Configure it correctly. + If you'd like to do it, you can also write a Makefile + yourself. +4. Hit build (or type make)! +5. If it failed, check step 2 and 3, then repeat step 4... + +Warning: +Some revisions in the svn repo has noticeable problems. +Always build the latest svn revision or official release! diff --git a/archive/blr2/Levels b/archive/blr2/Levels new file mode 100644 index 0000000..e22e9f4 --- /dev/null +++ b/archive/blr2/Levels @@ -0,0 +1,335 @@ +BulletLabRemixII +Level index/specifications/hints + +I'm still working on this document. +Please don't trouble me if it misled you. + +*Trying the levels before reading this is strongly recommended.* + +This document is probably NOT suitable for: +Anybody who isn't insterested in this topic +Liberal arts students(?...) + +This document is suitable for: +Nobody(?) +Coders who want to modify this game, or import levels to your game... +Casual persons who won't care anything +Someone who is stuck at a part + + + + + + +======================WARNING, LOTS OF WORDS BELOW!====================== +Level 1 2/180 +River levels 120 +-It's confusing... so much bullets for Level1? + However it's fairly easy. Do not seek for death(where those "+1" are + leading you to) + +Double-directed labyrinth 60 +-Still very easy. + +Level 2 4/215 +Polygon-red 60 +-This is not hard... + Fake bullets aren't always annoying. + +Polygon-white 60 +-Make good use of precise mode. + +Polygon-white locked 6 +-You can't move vertically! + Find a good position, e.g. near by a line. + +Polygon-both 30 +-This part doesn't make sense. + +Level 3 4/150 +Reflective 30 +-Just meet them, do not make big movements. + They are pretty friendly aren't they? + +*4 30 +-It's a little difficult... Keep away from the edges! + +Rotate ???? 60 +-Stay away from the rotating bullets. + +Wall of blues? 30 +-Rather easy. Do not try to earn too may semi-collisions unless + you are really skilled. + Looks awesome? + +Level 4 5/243 +Orange 30 +-Don't make big movements and stay away from the edges. (why?) + Those fast bullets are really annoying. + +Orange trap 5+5+4+4+3+3+2+2+5 +-Do NOT press shift! + +Double spinner 60 +-An easy part for level 4. + +Squash-2 60 +-Enjoy it yourself. + I think it may make the situation worse. + +Circle-drawing 60 +-Just draw the circle. + If you have any problem, try BLR 1. + +Level 5 8/338 +CChase 30+30 +-Don't set player move speed to 1! + Remark: They are not really faster than you... + +Vortex of leaves 60 +-This is another annoying level, looks awesome and hard. + Keep away from those 'laser''s! + Remark: The lasers may have strange collision detection... + Be careful! + +Upstream flow 60 +-Rather easy. + Looks like something in level 3. + +High speed threaten 30 +-It's JUST threaten! + Precision is important. + Practice makes perfect. + If you *can't* move horizonally may be it's easier... + +Crossing threaten 30 +-Appears very hard. + Choose the correct time to cross those bullets. + +Orange trap2 2+2+2+5 +-Just another level from level 4. + +Fish in the barrel 60 +-Seems to be faster and faster? NO... + Remark: Those bullets are comming directly towards you. + +the Unbreakable jail 30 +-This is fairly hard. Use CLR if you need it. + Remark: When the 'target' got red, it's about to update its + position. If you keep moving when it's updating its position, + it will stuck in update mode, or it will stop. + +Level 6 7/390 +Snow WHITE 30 +-Incredible fast. Do not treat your CLR as a + £100,000,000 cheque. + Remark: They are accelerated! + +Photokeratitis 10+10+10+10+10 +-This used to be sickly hard... + Treat fast bullets and slow bullets separately. + Remark: It looks like Wriggle Nightbug's spellcard... + As of r94, it's not so hard as it was before. Fast bullets + won't hit you *if you don't move*. + +Squash-4(?) 60 +-Do not be trapped! You only need ONE CLR!... + +Avalanche 60 +-Do not stay at the screen bottom, it's very dangerous... + +Dangerous target 60 +-Keep moving! + It's a nightmare if you've choose a slow player... + Remark: The target follows you as a yellow bullet does, + but not in the same manner. + +Hexagon loops 10+20+7+7+7+19 +-Step well back and watch the show. + Remark: This level will misbehave if FPS dropped... + +Hyperfluid 60 +-Also known as Superfluid. + In fact, liquid helium is not cold enough. It's still several + Kelvin's degrees. I can make it even colder. + Remark: The white bullets are not accelerated, which are different + from the blue ones. The blue bullets share the same direction: 45 deg. + Also will become easier if horizonal movement is restricted... + +Level 7 12/930+ Mapped levels +Spring thunder storm - panic? 60 Thunder storm... +-Although it's based on something from level 6, they are completely + different! + And this one is really easy. + Remark: Try to get to the top of the screen... + Try restricting vertical movement this time... + +Rainbow tower - color theory 90 rainbow tower +-Basic level. + Remark: It's taken from the old testbed version of BLRII. + +Rainbow bullets - nauty photon 60 Lazy level;) +-Similar to one part in level1, but *much* harder. + Luck is really required. + Remark: The generation of bullets is really strange... If the last position + on the y axis is taken up... sorry that I started to talk about coding again. + +Rainbow effect - appearance 60 draw a rainbow (of bullet) +-Random bullets. You will remember this part at once when you see the part. + If you feel it hard, go to assessment mode. + Remark: The bullets forming the rainbow are invincible. + +Rainbow effect - interference 120 as the name tells +-This part is REALLY easy... but why? + +Rainbow effect - diffraction 120 as the name tells +-Pretty hard. Those piles of shit may crash straight into you. + The code is pretty ugly too. + +Rainbow effect - photon school 60 "particalization"! +-Pretty hard. Use CLR if necessary. + It may be easier if you stay near the edges. (I don't really know.) + +Over the Rainbow - infinity challenge - great circles +-Your goal is to reach the red block... + And, this one is also pretty hard... + If you're not well-skilled and you are working on FPM, try --suicide--, + it worthwhile to do so! + Remark: This level will never end if you don't reach the red block... + +Trypophobia 120 another two classes: Tail & Pile +-Very hard. You'll never know where they will go next(neither will they). + However, they won't step on the same place twice. + Will this cause trypophobia? + Remark: This level almost burn my computer... + I seem to forget an important thing: Bullets with effects won't collide + for a short time after they are created... + +Photon fission 90 Use a slightly modified tower8... +-Directed bullets+random bullets. + Find a formula for it. + +Wave of Photon 60 class WOP+Lazy of particalization +-Not very hard at the beginning... + +Return to void 90 return (void)(...); +-VERY HARD!!! + I don't know where this came from. + CLR is useless but it will give you a short period during which you are invincible. + Remark: There are "no solution" cases... + +Level -1(Extreme) 7/1020 +unknown circles1 60 +-They slow down as they approach the border. VERY ANNOYING!!! + +unknown circles2 60 +-They STUCK at the border!! And they get THICKER and THICKER!!...... + +Spiky 120 +-Hard. Their behavior is not predictable. + Remark: Again, never try to approach lasers! They are harmful to your eyes... + +Achromatopsia 120(90+30) +-There's no way?! + Well, mind the name please... + Or we should call this "deuteranopia vs protanopia"? + Remark: Color change may suddenly happen!! + +Quad thread 120 +-Do you humans really support it? + Remark: I don't... + +Gravity vortex 120 +-It has nothing to do with gravity at all, but it's pretty + hard! + Seems to be very graceful. + +Supernova(additive blending) 120 +-After gathering enough power, they explode -- + Awesome supernova! + I enjoy coding(such easy parts)... + Remark: Newly created bullets are... I can't give more clue. + +yellow explosive 90 +-There's nothing to code, so I came up with this... + --Not deadly at all.-- + +Sink over the horizon 90 +-Strange. You will be easily trapped. + +Incomplete Reflective 120 +-Start in peace, end in mess. + Remark: one in four bullets will explode when it hits the wall. + +Level -2(Assess) 10/? + +You will certainly die. So let me predict your cause of death... + +Directed bullet +-This is actually a copy of... + Towers don't collide you, however they should do so. + You may end up in... whatever you want. + +Random bullet +-Pure random. + Are they getting faster? + You may end up in a huge mess. + +Constant patterns +-Pretty awesome. + Doesn't look like anything. + You may end up in a horror. + +Crossing 1(L+R) +-They started spinning!!! + You may end up like a juicy orange in a squeezer. + +Crossing 2(C) +-Used by Moriya Suwako... + Round bullets made me dizzy. + You may end up like... + That scene is really terrible! + +Trappy +-The name is strange... + Remark: The lasers created just over you are not created there on purpose... + However, one third of the bullets could be directed. + You may end up without your awareness. + +Sine wave +-Oscilloscope? + Find a good place to vibrate with the graph... + Remark: Some positions will cause death instantly! + You may end up... + Oops! I can't find you on that broken oscilloscope! + +Density test +-Really high density. + WTF? There's no way?! + You MUST end up in a horrible traffic accident, squeezing every drop of blood + out on the left board. That's really a bad image. + +"Pinballs" +-Well... They have collisions since r93! + These balls spawn with random velocity! + You may end up... + just imagine an eXtra-eXtra Large sized bowling ball flying direct towards you. + +Road Blocks +-You'll understand this one day. + --Flappy square?... + You death cause could be the same as the one in "Density test". + Don't ask why. I feel sick now... + +Extreme High speed +-Copy of one part in level 5. + You may end up in just *two* seconds. + +Laser crosses +-Only a show off of the Laser class. + You might end up like... Coal Dust? (Sorry I'm playing Industrial Craft2 these + days) + +Bonus test: Lunatic Lunar! +-May be the legacy of a vintage game... + You may end up... sorry, this in not predictable..
\ No newline at end of file diff --git a/archive/blr2/Levels.zh b/archive/blr2/Levels.zh new file mode 100644 index 0000000..123b1e6 --- /dev/null +++ b/archive/blr2/Levels.zh @@ -0,0 +1,330 @@ +BulletLabRemixII +å…³å¡åˆ—表ã€è¯´æ˜Žå’Œæ示 + +æ¤æ–‡æ¡£ä»æœªå®Œæˆã€‚ +å¦‚æžœå®ƒè¯¯å¯¼äº†ä½ ï¼Œä¹Ÿä¸è¦æ¥æ‰¾æˆ‘啊。。。 + +强烈推è在阅读本文档å‰å…ˆè‡ªå·±çŽ©ä¸€ä¸‹ã€‚ + +ä¸é€‚宜人群: +? + + + +适宜人群: +? + + + + + + + + + +======================è¦å‘Šï¼šä¸‹é¢æœ‰å¥½å¤šå¥½å¤šå—ï¼====================== +Level 1 2/180 +River levels 120 +-为什么第一关就这么多å弹… + 其实éžå¸¸ç®€å•ï¼Œåˆ«ä½œæ»å°±è¡Œã€‚(而那些“+1â€å°±æ˜¯è¦ä½ 这么åšã€‚) + +Double-directed labyrinth 60 +-还是éžå¸¸ç®€å•ã€‚ + +Level 2 4/215 +Polygon-red 60 +-这个也ä¸éš¾â€¦ + 外é¢é‚£ä¸€åœˆæ²¡æœ‰çœ‹ä¸ŠåŽ»çš„那么麻烦。 + +Polygon-white 60 +-利用好shift键(我的shift键已ç»å¡åœ¨é”®ç›˜é‡Œå¼¹ä¸å‡ºæ¥äº†ï¼‰ã€‚ + +Polygon-white locked 6 +-ä½ ä¸èƒ½åœ¨ç«–ç›´æ–¹å‘ä¸Šç§»åŠ¨äº†ï¼ + 找一个好的ä½ç½®å‘†ç€ã€‚ + +Polygon-both 30 +-è¿™å…³æ¯«æ— æ„义。 + +Level 3 4/150 +Reflective 30 +-åˆæ¬¡è§é¢ï¼Œå®ƒä»¬çœ‹èµ·æ¥è¿˜æŒºå‹å¥½çš„是å§ï¼Ÿ + +*4 30 +-ç¨å¾®æœ‰ç‚¹éš¾â€¦ç¦»è¾¹æ¡†è¿œç‚¹ï¼ + +Rotate ???? 60 +-ä¸è¦é 近那些旋转的å弹。 + +Wall of blues? 30 +-相当简å•ã€‚别刷擦蛋,除éžä½ 是大触。 + 看起æ¥å¾ˆåŽ‰å®³ï¼Ÿ + +Level 4 5/243 +Orange 30 +-高速åå¼¹éžå¸¸çƒ¦äººã€‚ + +Orange trap 5+5+4+4+3+3+2+2+5 +-别按shiftï¼ + +Double spinner 60 +-对于第4å…³æ¥è¯´ç®—是简å•çš„部分。 + +Squash-2 60 +-好好享å—… + 我想这å¯èƒ½ä¼šè®©æƒ…况å˜å¾—æ›´å。 + +Circle-drawing 60 +-画圈就行了。 + å¦‚æžœä½ æœ‰ä»»ä½•é—®é¢˜ï¼ŒåŽ»è¯•è¯•BLR 1. + +Level 5 8/338 +CChase 30+30 +-ä¸è¦æŠŠç§»åŠ¨é€Ÿåº¦è®¾ç½®ä¸º1ï¼ + 说明:它们ä¸æ˜¯çœŸçš„æ¯”ä½ å¿«â€¦ + +Vortex of leaves 60 +-å¦ä¸€ä¸ªçƒ¦äººçš„å…³å¡ï¼Œçœ‹ç€æŒºå¥½çœ‹ï¼Œä½†æ˜¯ä¹Ÿå¾ˆéš¾ã€‚ + 离那些“激光â€è¿œç‚¹ï¼ + 说明:激光的判定å¯èƒ½æœ‰ç‚¹å¥‡æ€ªã€‚ + +Upstream flow 60 +-相当简å•äº†ã€‚ + 看起æ¥æœ‰ç‚¹åƒç¬¬3关。 + +High speed threaten 30 +-è¿™åªæ˜¯å“å”¬äººçš„ï¼ + ä½ éœ€è¦ç²¾å‡†çš„移动。 + æˆ–è®¸å¦‚æžœä½ ä¸èƒ½æ°´å¹³ç§»åŠ¨çš„è¯è¿™å…³ä¼šç®€å•ä¸€ç‚¹â€¦ + +Crossing threaten 30 +-看起æ¥éžå¸¸éš¾ã€‚ + 选择æ£ç¡®çš„时机穿过它们。 + +Orange trap2 2+2+2+5 +-第4关? + +Fish in the barrel 60 +-好åƒè¶Šæ¥è¶Šå¿«äº†ï¼Ÿä¸â€¦ + 说明:那些å弹是“自机狙â€ã€‚ + +the Unbreakable jail 30 +-相当难…如果感觉到了请使用CLR。 + 说明:当那个“轮åâ€å˜çº¢çš„时候,它就è¦æ›´æ–°å®ƒçš„ä½ç½®äº†ã€‚å¦‚æžœä½ åœ¨å®ƒæ›´æ–°ä½ç½® + 的时候一直移动,它将å¡åœ¨æ›´æ–°æ¨¡å¼ï¼Œå¦åˆ™å®ƒä¼šåœä¸‹æ¥ã€‚ + +Level 6 7/390 +Snow WHITE 30 +-太快了…多用CLR… + è¯´æ˜Žï¼šå®ƒä»¬è¿˜è¢«åŠ é€Ÿäº†ï¼ + +Photokeratitis 10+10+10+10+10 +-这关曾ç»éš¾çš„丧心病狂… + 区别对待快速弹和慢速弹。 + 说明:看ç€æœ‰ç‚¹åƒè°çš„符å¡â€¦ + 到r94以åŽï¼Œè¿™å…³æ²¡æœ‰ä¹‹å‰é‚£ä¹ˆéš¾äº†ã€‚å¦‚æžœä½ ä¸åŠ¨çš„è¯ï¼Œå¿«é€Ÿå¼¹æ ¹æœ¬æ‰“ä¸åˆ°ä½ 。 + +Squash-4(?) 60 +-别被困在里é¢ï¼ä½ åªéœ€è¦ä¸€ä¸ªCLRï¼ + +Avalanche 60 +-ä¸è¦å‘†åœ¨å±å¹•åº•ç«¯ï¼Œé‚£é‡Œéžå¸¸å±é™©â€¦ + +Dangerous target 60 +-别åœä¸‹æ¥ï¼ + å¦‚æžœä½ çš„ç§»åŠ¨é€Ÿåº¦è®¾ç½®çš„å¾ˆæ…¢ï¼Œé‚£è¿™å°†æ˜¯ä¸€åœºå™©æ¢¦â€¦ + 说明:“轮åâ€å°±åƒé»„色åå¼¹ä¸€æ ·è·Ÿç€ä½ ,但是姿势ä¸åŒã€‚ + +Hexagon loops 10+20+7+7+7+19 +-找个角è½åœä¸‹æ¥ç„¶åŽè§‚看表演。 + 说明:如果FPS低于55,那么这关å¯èƒ½ä¼šå˜å½¢â€¦ + +Hyperfluid 60 +-超æµä½“。 + 其实液氦还ä¸å¤Ÿå†·ï¼Œæœ¬æ¥è¿™éƒ¨åˆ†è¿˜å¯ä»¥æ›´å†·ä¸€äº›çš„… + 说明:è“色åå¼¹æ˜¯åŠ é€Ÿçš„ï¼Œè€Œç™½è‰²çš„æ²¡æœ‰ã€‚æ‰€æœ‰è“色å弹的方å‘都是相åŒçš„。 + 如果é™åˆ¶æ°´å¹³ç§»åŠ¨çš„è¯ä¼šç®€å•ä¸€äº›ã€‚ + +Level 7 12/930+ Mapped levels +Spring thunder storm - panic? 60 Thunder storm... +-虽然代ç 是基于上一关写的(看ç€ä¹Ÿå¾ˆåƒï¼‰ï¼Œä½†æ˜¯å®ƒä»¬å®Œå…¨ä¸åŒï¼ + 这个真的很简å•â€¦ + 说明:试ç€åœ¨å±å¹•é¡¶ç«¯èº²é¿â€¦ + 这次试ç€é™åˆ¶ä¸€ä¸‹ç«–ç›´æ–¹å‘的移动… + +Rainbow tower - color theory 90 rainbow tower +-基础的关å¡ã€‚ + 说明:这关是从很è€çš„试验版本的BLR2ä¸æ‹¿å‡ºæ¥çš„。 + +Rainbow bullets - nauty photon 60 Lazy level;) +-看ç€å¾ˆåƒç¬¬ä¸€å…³çš„ä»€ä¹ˆä¸œè¥¿ï¼Œä½†æ˜¯éš¾å¤šäº†ï¼ + 很拼RP… + 说明:生æˆå弹的过程比较奇怪…… + +Rainbow effect - appearance 60 draw a rainbow (of bullet) +-éšæœºå¼¹ã€‚ä½ ä¸€çœ‹åˆ°è¿™ä¸€å…³å°±ä¼šè®°ä½å®ƒçš„。 + å¦‚æžœä½ æ„Ÿè§‰å¤ªéš¾ï¼Œè¯•è¯•è¯„ä¼°æ¨¡å¼å§ã€‚ + 说明:组æˆå½©è™¹çš„å弹是ä¸ä¼šè¢«æ¶ˆæŽ‰çš„。 + +Rainbow effect - interference 120 as the name tells +-*真的*太简å•äº†â€¦ä½†æ˜¯ä¸ºä»€ä¹ˆå‘¢ï¼Ÿ + +Rainbow effect - diffraction 120 as the name tells +-相当难。那一大å¨æœ‰å¯èƒ½ç³Šä½ 一脸。 + 代ç 也很难看。 + +Rainbow effect - photon school 60 "particalization"! +-ä»ç„¶ç›¸å½“难(æŸäººï¼šè¿™éƒ½ç¬¬å‡ å…³äº†ä½ ä¹Ÿä¸çœ‹çœ‹â€¦â€¦ï¼‰ + å¦‚æžœä½ é 近边缘的è¯å¯èƒ½ä¼šç®€å•ä¸€ç‚¹ï¼ˆå…¶å®žæˆ‘ä¸çŸ¥é“)。 + +Over the Rainbow - infinity challenge - great circles +-ä½ çš„ç›®æ ‡æ˜¯å†²åˆ°çº¢æ ¼å上… + 并且这个也很难…… + å¦‚æžœä½ æŠ€æœ¯ä¸è¿‡å…³ï¼Œå¹¶ä¸”在玩自由模å¼ï¼Œè¯•è¯•â€œè‡ªæ€â€ï¼ˆ<-åˆ é™¤çº¿ï¼‰ï¼Œè¿™æ¯”â€œå¥½å¥½çŽ©â€è¦ç»æµŽå¾—å¤šï¼ + è¯´æ˜Žï¼šå¦‚æžœä½ ä¸åŽ»ç¢°é‚£ä¸ªçº¢æ ¼å,这关永远ä¸ä¼šç»“æŸâ€¦â€¦ + +Trypophobia 120 another two classes: Tail & Pile +-éžå¸¸éš¾ã€‚ä½ æ°¸è¿œä¸çŸ¥é“它们接下æ¥ä¼šè¿›å…¥å“ªä¸ªæ ¼å(它们自己也ä¸çŸ¥é“)。 + 但是它们ä¸ä¼šè¸ä¸ŠåŒä¸€ä¸ªæ ¼å两次。 + 这会引起密集æ惧症å—? + è¯´æ˜Žï¼šè¿™å…³å‡ ä¹Žè¦çƒ§æŽ‰æˆ‘的电脑了…… + 我好åƒå¿˜äº†ä¸€ä»¶é‡è¦çš„事情:刚生æˆçš„带生æˆæ•ˆæžœçš„å弹是没有碰撞判定的… + +Photon fission 90 Use a slightly modified tower8... +-自机狙+éšæœºå¼¹ã€‚ + 这是有公å¼çš„… + +Wave of Photon 60 class WOP+Lazy of particalization +-一开始一点也ä¸éš¾â€¦ + +Return to void 90 return (void)(...); +-éžå¸¸éš¾ï¼ï¼ï¼ï¼ˆæ±‰å—ä¸èƒ½å¤§å†™çœŸæ˜¯å¤ªé—憾了。) + 我ä¸çŸ¥é“这是从哪儿æ¥çš„。 + CLRæ²¡ä»€ä¹ˆç”¨å¤„ï¼Œä½†æ˜¯å®ƒä¼šç»™ä½ çŸæš‚çš„æ— æ•Œæ—¶é—´â€¦ + è¯´æ˜Žï¼šæœ‰æ— è§£çš„æƒ…å†µâ€¦ + +Level -1(Extreme) 7/1020 +unknown circles1 60 +-它们é 近边缘的时候会慢下æ¥ã€‚*实在是太烦人了ï¼ï¼ï¼* + +unknown circles2 60 +-å®ƒä»¬ç›´æŽ¥å †ç§¯åœ¨è¾¹ç¼˜é™„è¿‘äº†ï¼è€Œä¸”å˜å¾—越æ¥è¶ŠåŽšï¼ï¼â€¦â€¦ + +Spiky 120 +-一个å—:难ï¼å®ƒä»¬çš„è¡Œä¸ºæ˜¯æ— æ³•é¢„æµ‹çš„ã€‚ + 说明:é‡å¤ä¸€é,ä¸è¦ç¢°æ¿€å…‰ï¼ä¼šä¼¤å®³çœ¼ç›çš„… + +Achromatopsia 120(90+30) +-没有路了? + 好好看看这关的åå—(色盲)…… + 或者我们å¯ä»¥æŠŠè¿™å…³å«åš"绿色盲 vs 红色盲"? + 说明:颜色å˜æ¢æ˜¯çªç„¶å‘ç”Ÿçš„ï¼ + +Quad thread 120 +-人类大脑真的支æŒè¿™ä¸ªä¹ˆï¼Ÿ + 说明:我的ä¸è¡Œâ€¦ + +Gravity vortex 120 +-è·Ÿå¼•åŠ›ä»€ä¹ˆçš„ä¸€ç‚¹å…³ç³»éƒ½æ²¡æœ‰ï¼Œä½†æ˜¯å¾ˆéš¾ï¼ + 看ç€æŒºå¥½çœ‹ã€‚ + +Supernova(additive blending) 120 +-积攒了足够的能é‡ä¹‹åŽï¼Œå®ƒä»¬çˆ†ç‚¸äº†â€”â€”è¶…æ–°æ˜Ÿï¼ + 我éžå¸¸æ„¿æ„写这ç§ç®€å•çš„å…³å¡â€¦ + 说明:刚生æˆçš„å弹…我ä¸èƒ½æ示更多了。 + +yellow explosive 90 +-没什么å¯å†™çš„关了,于是我就想到了这个。 + --一点也ä¸è‡´å‘½ã€‚-- + +Sink over the horizon 90 +-éžå¸¸å¥‡æ€ªã€‚ç»å¸¸èŽ«å其妙的被å°ã€‚ + +Incomplete Reflective 120 +-在平é™ä¸å¼€å§‹ï¼Œä¸€å›¢ç³Ÿä¸ç»“æŸã€‚ + 说明:有四分之一的å弹会在碰到墙时爆炸。 + Remark: one in four bullets will explode when it hits the wall. + +Level -2(Assess) 10/? +“评估â€å…³å¡ + +ç”±äºŽä½ åˆ°æœ€åŽè‚¯å®šä¼šæ»ï¼Œæ‰€ä»¥æˆ‘æ¥è¯•ç€é¢„æµ‹ä¸€ä¸‹ä½ çš„æ»å› å§â€¦ + +Directed bullet +定å‘åå¼¹ +-这其实åˆæ˜¯å¤åˆ¶çš„什么…… + “塔â€å¹¶ä¸ä¼šå½±å“ä½ ï¼Œä½†è¿™å…¶å®žä¸æ˜¯æˆ‘想è¦çš„… + ä½ çš„ç»“å±€å¯èƒ½æ˜¯â€¦è¿™å…³çŽ©æˆä»€ä¹ˆæ ·éƒ½æœ‰å¯èƒ½å•Šã€‚ + +Random bullet +éšæœºåå¼¹ +-彻彻底底的éšæœºã€‚ + 它们在å˜å¿«ï¼Ÿ + ä½ ä¼šåœ¨ä¸€ç‰‡æ··ä¹±ä¸ç»“æŸæ—…程。(我猜的) + +Constant patterns +固定的图案 +-挺好看的(…) + 但是什么都ä¸åƒã€‚ + 结局:在æ惧ä¸è¢«å¹²æŽ‰ï¼Ÿ + +Crossing 1(L+R) +交å‰1(左å³ï¼‰ +-它们转起æ¥äº†ï¼ + 结局:想象一下榨æ±æœºä¸å¤šæ±çš„æ©™å。 + +Crossing 2(C) +交å‰2 +-直接æ¥è‡ªæ³„矢 诹访å的符å¡ã€‚ + 圆形的å弹有点令人晕头转å‘。 + ç»“å±€ï¼šä½ çŒœï¼Ÿ + +Trappy +陷阱(形容è¯â€¦ï¼‰ +-åå—很奇怪… + 说明:激光没有故æ„被生æˆåœ¨ä½ çš„ä½ç½®ã€‚ + 但是,有三分之一的å¯èƒ½æ€§ï¼Œå®ƒä»¬ç”Ÿæˆçš„å弹会æœä½ 飞过æ¥ã€‚ + ç»“å±€ï¼šä½ åœ¨æ’žä¸ŠåŽ»ä¹‹å‰è¿˜ä»€ä¹ˆéƒ½ä¸çŸ¥é“? + +Sine wave +æ£å¼¦æ³¢ +-示波器? + 找一个åˆé€‚çš„ä½ç½®ï¼Œè·Ÿå›¾åƒä¸€èµ·æŒ¯åŠ¨â€¦ + è¯´æ˜Žï¼šæœ‰äº›åœ°æ–¹æ˜¯ç§’æ’žçš„ï¼ + 结局:喂,我在那个å掉的示波器上找ä¸åˆ°ä½ 啊… + +Density test +密度测试 +-这个密度真的很高… + ××?ï¼æ²¡è·¯äº†ï¼Ÿ + 结局: + 玩家××× + æ»äºŽä¸€åœºå¯æ€•çš„车祸,æ¯æ»´è¡€éƒ½è¢«*挤*到了左边的墙上。 + 这景象真是有点å¯æ€•ã€‚ + +"Pinballs" +“弹çƒâ€ +-从r93å¼€å§‹ï¼Œå®ƒä»¬ä¹‹é—´ä¹Ÿä¼šç¢°æ’žäº†ï¼ + 这些çƒç”Ÿæˆæ—¶é€Ÿåº¦æ˜¯éšæœºçš„。 + 结局:想象一个大å·çš„ä¿é¾„çƒå†²ä½ 飞了过æ¥ã€‚ + +Road Blocks +路障 +-æœ€ç»ˆä½ è¿˜æ˜¯èƒ½ç†è§£è¿™ä¸ªçš„… + --Flappy square?... + 结局:å¯èƒ½è·Ÿâ€œå¯†åº¦æµ‹è¯•â€é‚£å…³å¾ˆåƒã€‚ + 别问为什么,现在我有点想å…… + +Extreme High speed +超高速 +-和第5å…³æŸéƒ¨åˆ†ç±»ä¼¼ã€‚ + ä½ å¯èƒ½ä¸åˆ°ä¸¤ç§’å°±æ’žäº†ï¼ + +Laser crosses +-炫耀激光class? + 结局:煤粉?(对ä¸èµ·ï¼Œæˆ‘最近一直在玩工业2…) + +Bonus test: Lunatic Lunar! +奖励:Lunatic Lunar! +-æŸä¸ªå¤è€æ¸¸æˆçš„什么é—产? + 结局:ä¸èƒ½é¢„测。
\ No newline at end of file diff --git a/archive/blr2/Readme b/archive/blr2/Readme new file mode 100644 index 0000000..9161aca --- /dev/null +++ b/archive/blr2/Readme @@ -0,0 +1,288 @@ +This text is encoded in UTF-8. + +This file is mainly about BulletLabRemix II. BulletLabRemix III is still under +heavy development and can be found in the 'src' directory. The implementation +of the script virtual machine is mostly complete, although many functions are +still unimplemented. + + +BulletLabRemix II readme + +Content +------------------------------------------------------------------------------------ +What's this? +Story +Generic Information +Game Modes +Command line options +About the author +"Black History" +Brief History + +What's this? +------------------------------------------------------------------------------------ +"As the name tells", it's the continue, or "free" replacement of Bullet LAB from +Game Boltz, which is a tiny flash game. Having no proprietary software dependences, +it's goal is making the original game "free" and more challanging. + +This is the second work of BulletLabRemix. Compared to the first work, it's much +more mature. However, it's still far away from a complete "framework". And it may +be full of bugs... + +Story +------------------------------------------------------------------------------------ +THE STORY OF THE COLOURS +Once upon a time the colors of the world started to quarrel, all claimed that they +were the best the most important the most useful the favorite. +GREEN said: +「Clearly I am the most important. I am the sign of life and of hope. I was chosen +for grass and trees leaves. Without me all animals would die. Look over the +countryside and you will see that I am in the majority.〠+BLUE interrupted... +「You only think about the earth but consider the sky and the sea. It is the water +that is the basis of life and drawn up by the clouds from the deep sea. The sky +gives space and peace and serenity. Without my peace you would all be nothing.〠+YELLOW chuckled: +「You are all so serious. I bring laughter gaiety and warmth into the world. The +sun is yellow, the moon is yellow and the stars are yellow. Every time you look at +a sunflower, the whole world starts to smile. Without me there would be no fun.〠+ORANGE started next to blow her trumpet. +「I am the color of health and strength. I may be scarce but I am precious, for I +serve the needs of human life. I carry the most important vitamins. Think of +carrots, pumpkins, oranges, mangoes and pawpaws. I don't hang around all the time +but when I fill the sky at sunrise or sunset, my beauty is so striking that no one +gives another thought to any of you.〠+RED could stand it no longer. He shouted out: +「I am the ruler of all of you - I am +blood - lifes blood I am the color of danger and of bravery. I am willing to fight +for a cause. I bring fire into the blood. Without me the earth would be as empty as +the moon. I am the color of passion and of love, the red rose, the poinsettia and +the poppy.〠+PURPLE rose up to his full height. He was very tall and spoke with great pomp: +「I am the color of royalty and power. Kings chiefs and bishops have always chosen +me for I am the sign of authority and wisdom. People do not question me - they +listen and obey.〠+Finally INDIGO spoke much more quietly than all the others but with just as much +determination: +「Think of me. I am the color of silence. You hardly notice me but without me you +all become superficial. I represent thought and reflection twilight and deep water. +You need me for balance and contrast for prayer and inner peace.〠+And so the colors went on boasting each convinced of his or her own superiority. +Their quarreling became louder and louder. Suddenly there was a startling flash of +bright lightening - thunder rolled and boomed. Rain started to pour down +relentlessly. The colors crouched down in fear drawing close to one another for +comfort. +In the midst of the clamor rain began to speak: +「You foolish colors fighting amongst yourselves, each trying to dominate the rest. +Don't you know that you were each made for a special purpose, unique and different? +Join hands with one another and come to me!〠+Doing as they were told, the colors united and joined hands. The rain continued: +「From now on when it rains each of you will stretch across the sky in a great bow +of color as a reminder that you can all live in peace. The rainbow is a sign of +hope for tomorrow. And so whenever a good rain washes the world and a rainbow +appears in the sky let us remember to appreciate one another.〠+------------------------------------------------------------------------------------ +Well, that was about hundreds of thousand years ago. +After a catastrophic disaster, they found some of them were missing... +------------------------------------------------------------------------------------ + +Generic Information +------------------------------------------------------------------------------------ +My own comment on this game... +A "game" filled with the smell of mysterious science and imagination(3:2 approximately). +(I worked on it for almost 9 months, after all.) +Others' comments... +-PIECE OF SHIT!!! +-The author must be suffering from serious mental problems.(I agree...) +-(literally translated from Chinese) Revenge on society... + +Requirements & Recommends +Basic environment: +CPU: 1GHz. +RAM: 256MiB. +GPU&VRAM: With DirectX 9+/OpenGL 1.2+ support. +OS*: Windows XP+ & DirectX 9 / Linux kernel 2.6+ & OpenGL 1.2+ +Recommended environment: +CPU: Lots of cores. +GPU&VRAM: Very fast graphic rendering. +Sound: Ability to run OpenAL software version. + +*: According to Micro$oft and MinGW, this game should also run in Windows +98(SE)/ME**, but who's still using that? +**: The source code is just there. You can even port it to MS-DOS... + +MORE Recommends... +-SERIOUSLY, NO Trypophobia! +-CheatEngine(skip levels, obtain more Clear Range's, and more...) +-Some editors or compilers(If you find this impossible and want to make it easier) +-(Additionally for the last one)Ability to read non human-readable code. +-Achromatopsia(<-strikethrough) + +How to install&run it... +Windows: +Just extract all files in the archive somewhere, then start the only executable +file in it. +Linux: +See INSTALL. + +If, suddenly, you can't run it one day... +Remove .blrrc then restart the game. +It will ask you for initial settings. +If this can't solve your problem, read FAQ.TXT for more. + +If you think something went wrong... +Go to FAQ.txt. + +To Dear Windows Users +This game is developed and tested mostly under Linux. The official Windows version is also +built under Linux(awesome, isn't it?). It's only briefly tested. + +How to play it? +This section has been moved to the built-in help. Select "help" in the main menu to view +it. + +Menus +----------------------------------------------------------------------- +Main menu + +Start Select a mode and start the game. +Highscores View highscores +Options Settings and Options +About A dull credits list. +Exit Parents are coming!! + +Game Modes +----------------------------------------------------------------------- +Classic +The game ends instantly if you get a collision. However you can choose +to continue... + +This mode kills your time silently. + +Assessment Mode +You are the frog being boiled: all levels get harder as time goes. +You'll be brought to the next part if you had a collision. + +Most levels are designed to be IMPOSSIBLE after the elapsed time have +exceeded a certain value. + +Go for the highest score! + +Free Play Mode +You'll never die! Enjoy!... + +Options +----------------------------------------------------------------------- +Fullscreen Toggles fullscreen. Requires restart. You can also try Alt+Enter. +VSync Toggles vsync. If your screen refresh rate is 60Hz, enable it. +Clear Range Key Select key for calling/charging CLR. +Resolution Select a resolution. Please note that the native reso. is 800x600. +Music Volume Change music volume. +SFX Volume Change SFX volume. +Player Preference See below. + +Player Preference +------------------------------------------------ +Moving Speed Speed when moving without holding shift. +Precise Moving Speed Speed when moving holding shift. +Clear Range Bonus Get more CLR's for each part. +Clear Range Mode Change CLR mode. +Ability Point If this value is greater than 10000, you can't save your settings. + +Command line options +------------------------------------------------------------------------------------ +Yes, it accept command line options! (And some of them may be very useful...) +You can override your settings with them if you can't start it after changing the settings. +However they may cause strange behavior or crashes. So use with caution. +Invalid parameters may cause unexpected behavior, (e.g. --start with inappropriate parameters) +they should be used for debug purpose. But if you use it for cheating, I'm not against it. +If it's run without arguments, the game will start normally. +Otherwise... see below. +--help Print command line usage and exit. +--version Print version and exit. +--start=x,y Start free play mode directly from level x part y. The part must be valid. +--nosound Forcibly use no sound. +--fullscreen=1/0 Forcibly use fullscreen/windowed. This will override your configuration. +--vidmode=0~4 Forcibly use specific video mode instead the one in the configuration. + 0 800x600 (native resolution) + 1 640x480 + 2 960x720 + 3 1024x768 + 4 1280x960 +--firststartup Forcibly run first start up. The score file will be preserved if exist. +--fast Fast mode. All levels are two times shorter. +--logfile=... Use an alternate log file name instead of the default "BLRLOG.txt". +--nohideconsole Do not hide console (Windows version only). + +About the author +------------------------------------------------------------------------------------ +-Senseless(this word has multiple means...) +-Often know nothing to do next. If I accidently got it, I would do it at once. +(slowly, though) +-「The perfect balance of code length and efficiency 〠+-One of those "who (like to) live on the edge". --according to Debian maintainers. +-Strange (as many people say) + +This is my first(or second?) time making so big a project. So, this game is written +for a "framework" rather than the game itself. However, the "framework" seems to be +very incomplete till now. Everything is still code...(Maybe this is just the +"framework"?) + +Well, one day textures may also become code... That is, all textures will be drawn +to the memory during the initialization... + +"Black History" +------------------------------------------------------------------------------------ +This game first started as an simple hge&c++ rewrite of the original game "BulletLab". +For an unknown reason, it became bigger and bigger, the core of hge is even altered. +Several months or so after the creation of the project, BLRI(aka "The Creature of +Colour") released. + +As BLRI was being finished, BLRII was forked from the code base of BLRI. +Several "testbed" version was created over the code base of BLRI. +Then the pre-release version created. Almost all original code from BLRI is removed. +Now it has reached a position that I've never expected... + +See "The development" in the file "Extras" for more details. + +Brief History +------------------------------------------------------------------------------------ +The file ChangeLog contains the full history of this project. +Here's a list of released-to-public versions. +0.9.9-0 (r99) +The final Release Candidate. Complete the whole game system. +Fixing most of the bugs. + +0.9.1-1_PR (r86) +Comes with all levels that will appear in the final release. +Done menu rewrite. +Make multiplier system functional. + +0.7.3-0_PR (b73) +Comes with all seven "normal" levels. +Many bug fixes, making the Windows port (almost) stable. +Huge code changes happened here. + +0.4.4-0_PRG (b37a) +Comes with four levels and some parts of the fifth level. +Contains several bug fixes. + +0.2.9-1_PR (b21) +First public prerelease version. +Comes with two levels. +Introduced multiplier system, not functional yet. + +0.1.7-2_PR (b16) +Level 1 is finished. + +TB130907 (b10) +Laser implementation rev 2. + +TB130827 (b8) +Initial laser implementation. + +TB130620~TB130818 (b1~b7) +New towers and new levels. + +TB130610 (b0) +Creation of the Testbed version.
\ No newline at end of file diff --git a/archive/blr2/Readme.zh b/archive/blr2/Readme.zh new file mode 100644 index 0000000..f712fca --- /dev/null +++ b/archive/blr2/Readme.zh @@ -0,0 +1,274 @@ +This text is encoded in UTF-8. +这是一个æå‰å‘布的版本,这æ„味ç€ï¼š +-它å¯èƒ½ä¼šå´©æºƒï¼Œç”šè‡³å¯¼è‡´æ•°æ®ä¸¢å¤±ã€‚ +-奇怪的行为。 +-代ç 都å¯èƒ½ç¼–译ä¸äº†ï¼ + +BulletLabRemix II Readme - 一个类似机翻的ä¸æ–‡ç‰ˆ + +目录 +------------------------------------------------------------------------------------ +这是什么? +背景 +æ¦‚è¦ +æ¨¡å¼ +命令行选项 +关于作者 +åŽ†å² +简çŸçš„ç‰ˆæœ¬åŽ†å² + + +这是什么? +------------------------------------------------------------------------------------ +“æ£å¦‚åå—å‘Šè¯‰ä½ çš„â€ï¼Œå®ƒæ˜¯GameBoltz的一个å°flash游æˆâ€”—Bullet LAB的延ç»ï¼Œæˆ–者“自由â€æ›¿ä»£å“。 +它ä¸ä¾èµ–ä»»ä½•ä¸“æœ‰çš„è½¯ä»¶ã€‚å®ƒçš„ç›®æ ‡æ˜¯è®©åŽŸæ¸¸æˆå˜å¾—“自由â€å¹¶ä¸”更具挑战性。 +这是BulletLabRemix的第二个版本。与第一个版本比起æ¥ï¼Œå®ƒæˆç†Ÿå¾—多。但是,它离一个完整的“框架â€è¿˜å·®å¾—远。 +并且它还有å¯èƒ½åˆ°å¤„是bug… + +背景 +------------------------------------------------------------------------------------ +//å¬è¯´å·²ç»æ˜¯é«˜ä¸è‹±è¯å®Œåž‹å¡«ç©ºäº†ï¼Œå°±å·æ‡’ä¸ç¿»è¯‘了… +THE STORY OF THE COLOURS +Once upon a time the colors of the world started to quarrel, all claimed that they +were the best the most important the most useful the favorite. +GREEN said: +「Clearly I am the most important. I am the sign of life and of hope. I was chosen +for grass and trees leaves. Without me all animals would die. Look over the +countryside and you will see that I am in the majority.〠+BLUE interrupted... +「You only think about the earth but consider the sky and the sea. It is the water +that is the basis of life and drawn up by the clouds from the deep sea. The sky +gives space and peace and serenity. Without my peace you would all be nothing.〠+YELLOW chuckled: +「You are all so serious. I bring laughter gaiety and warmth into the world. The +sun is yellow, the moon is yellow and the stars are yellow. Every time you look at +a sunflower, the whole world starts to smile. Without me there would be no fun.〠+ORANGE started next to blow her trumpet. +「I am the color of health and strength. I may be scarce but I am precious, for I +serve the needs of human life. I carry the most important vitamins. Think of +carrots, pumpkins, oranges, mangoes and pawpaws. I don't hang around all the time +but when I fill the sky at sunrise or sunset, my beauty is so striking that no one +gives another thought to any of you.〠+RED could stand it no longer. He shouted out: +「I am the ruler of all of you - I am +blood - lifes blood I am the color of danger and of bravery. I am willing to fight +for a cause. I bring fire into the blood. Without me the earth would be as empty as +the moon. I am the color of passion and of love, the red rose, the poinsettia and +the poppy.〠+PURPLE rose up to his full height. He was very tall and spoke with great pomp: +「I am the color of royalty and power. Kings chiefs and bishops have always chosen +me for I am the sign of authority and wisdom. People do not question me - they +listen and obey.〠+Finally INDIGO spoke much more quietly than all the others but with just as much +determination: +「Think of me. I am the color of silence. You hardly notice me but without me you +all become superficial. I represent thought and reflection twilight and deep water. +You need me for balance and contrast for prayer and inner peace.〠+And so the colors went on boasting each convinced of his or her own superiority. +Their quarreling became louder and louder. Suddenly there was a startling flash of +bright lightening - thunder rolled and boomed. Rain started to pour down +relentlessly. The colors crouched down in fear drawing close to one another for +comfort. +In the midst of the clamor rain began to speak: +「You foolish colors fighting amongst yourselves, each trying to dominate the rest. +Don't you know that you were each made for a special purpose, unique and different? +Join hands with one another and come to me!〠+Doing as they were told, the colors united and joined hands. The rain continued: +「From now on when it rains each of you will stretch across the sky in a great bow +of color as a reminder that you can all live in peace. The rainbow is a sign of +hope for tomorrow. And so whenever a good rain washes the world and a rainbow +appears in the sky let us remember to appreciate one another.〠+------------------------------------------------------------------------------------ +Well, that was about hundreds of thousand years ago. +After a catastrophic disaster, they found some of them were missing... +------------------------------------------------------------------------------------ + +æ¦‚è¦ +------------------------------------------------------------------------------------ +本人对该游æˆçš„看法 +一个充斥ç€ç¥žç§˜çš„科å¦å’Œæƒ³è±¡æ°”æ¯çš„「游æˆã€ï¼ˆå¤§çº¦æœ‰3:2?) +(毕竟是9个月的工作啊) +别人的看法… +-「一å¨å±Žï¼ï¼ï¼ã€ +-「作者有精神疾病?ã€ï¼ˆæˆ‘åŒæ„…) +-「报å¤ç¤¾ä¼šï¼Ÿã€ + +è¿è¡ŒçŽ¯å¢ƒè¦æ±‚&推è项目 +必需环境: +CPU: 1GHz. +RAM: 256MiB. +GPU&VRAM: 支æŒDirectX 9+或者OpenGL 1.2+. +æ“作系统*: Windows XP+ & DirectX 9 / Linux kernel 2.6+ & OpenGL 1.2+ +推è环境: +CPU: 大é‡çš„处ç†å™¨æ ¸å¿ƒã€‚ +GPU&VRAM: éžå¸¸å¿«çš„渲染速度。 +声音: 能够è¿è¡ŒOpenAL软件版。 + +*: æ ¹æ®å¾®è½¯å’ŒMinGW的说法,本游æˆ*应该*也能在Windows 98(SE)/ME**下è¿è¡Œã€‚ä½†æ˜¯è° +还在用那ç§ä¸œè¥¿å‘¢ï¼Ÿâ€¦ +**: åæ£æºä»£ç éƒ½æœ‰ã€‚ä½ ç”šè‡³å¯ä»¥è€ƒè™‘把它移æ¤åˆ°MS-DOS… + +*更多*推è项目…: +-严肃的一项:ä¸èƒ½æœ‰å¯†é›†ææƒ§ç—‡ï¼ +-CheatEngine(跳关,获å–更多CLR…) +-编辑器和编译器(å¦‚æžœä½ å‘现它太难,想è¦è®©å®ƒå˜ç®€å•äº›) +-(é™„åŠ åœ¨ä¸Šä¸€æ¡ä¹‹ä¸Š)能读懂åŠå…¶ä¸‘陋的代ç 。 +-全色盲(<-åˆ é™¤çº¿) + +如何安装/è¿è¡Œå®ƒâ€¦ +Windows: +åªéœ€è¦æŠŠåŽ‹ç¼©åŒ…ä¸çš„所有文件解压到æŸä¸ªåœ°æ–¹ï¼Œç„¶åŽè¿è¡Œå…¶ä¸å”¯ä¸€çš„一个å¯æ‰§è¡Œç¨‹åºå°±è¡Œäº†ã€‚ +Linux: +è§INSTALL文件。 + +å¦‚æžœæœ‰ä¸€å¤©ä½ çªç„¶æ— 法è¿è¡Œå®ƒäº†â€¦ +åˆ æŽ‰.blrrc然åŽé‡æ–°è¿è¡Œã€‚它会é‡æ–°è¿›è¡Œåˆå§‹åŒ–设定。 +å¦‚æžœè¿™æ ·æ— æ³•è§£å†³ä½ çš„é—®é¢˜ï¼ŒåŽ»çœ‹çœ‹FAQ.TXT。 + +å¦‚æžœä½ è®¤ä¸ºä»€ä¹ˆä¸œè¥¿å‡ºé”™äº†â€¦ +->FAQ.TXT + +致亲爱的Windows用户 +å¼€å‘和测试基本是在Linux下进行的。å‘布的Windows版也是从Linux下编译的(å¬èµ·æ¥å¾ˆåŽ‰å®³ï¼Ÿï¼‰ã€‚Windows版 +åªè¿›è¡Œè¿‡ç®€å•çš„测试。 + +怎么玩? +这部分已ç»ç§»åŠ¨åˆ°æ¸¸æˆå†…的帮助里了,它在主èœå•çš„help选项ä¸ã€‚ +如果您看ä¸æ‡‚,建议使用机器翻译… + +èœå• +------------------------------------------------------------------------------------ +主èœå• +----------------------------------------------------------------------- +Start 选择一个模å¼å¹¶å¼€å§‹æ¸¸æˆã€‚ +Highscores æµè§ˆé«˜åˆ†è®°å½•ã€‚ +Options 设置和选项。 +About ä¸€ä¸ªæ— èŠçš„制作人员åå•ã€‚ +Exit ××æ¥äº†ï¼ + +æ¨¡å¼ +----------------------------------------------------------------------- +Classic ç»å…¸æ¨¡å¼ +ä¸€æ—¦ä½ ç¢°åˆ°äº†ä»»ä½•æœ‰åˆ¤å®šçš„ä¸œè¥¿å°±ç«‹åˆ»ç»“æŸæ¸¸æˆã€‚ä¸è¿‡ä½ å¯ä»¥é€‰æ‹©ç»§ç»â€¦ + +è¿™ç§æ¨¡å¼éžå¸¸æµªè´¹æ—¶é—´â€¦ + +Assessment Mode 评分/æ£€æµ‹æ¨¡å¼ +温水煮é’蛙实验:所有的关å¡éƒ½ä¼šéšç€æ—¶é—´æµé€è€Œå˜éš¾ã€‚ +å¦‚æžœä½ æ’žåˆ°äº†æœ‰åˆ¤å®šçš„ä¸œè¥¿ï¼Œå°±ä¼šè¿›å…¥ä¸‹ä¸€å…³â€¦ + +大多数的关å¡æœ€åŽéƒ½ä¼šå˜æˆæ— 法通过的…(当时间超过æŸä¸ªè®¾å®šå¥½çš„值之åŽï¼‰ + +试ç€æ’‘过最长的时间å§ï¼ + +Free Play Mode è‡ªç”±æ¨¡å¼ +永远ä¸ä¼šæ»çš„模å¼ï¼â€¦ + +选项 +----------------------------------------------------------------------- +Fullscreen 是å¦å…¨å±ã€‚é‡å¯ç¨‹åºåŽç”Ÿæ•ˆã€‚ä½ ä¹Ÿå¯ä»¥è¯•è¯•Alt+回车。 +VSync 是å¦å¼€å¯åž‚ç›´åŒæ¥ã€‚å¦‚æžœä½ çš„å±å¹•åˆ·æ–°çŽ‡æ˜¯60Hzå°±å¯ç”¨å®ƒã€‚ +Clear Range Key 选择一个用于使用CLR或为CLR“蓄力â€çš„键。 +Resolution 选择分辨率。默认分辨率是800x600。 +Music Volume 更改背景音ä¹çš„音é‡ã€‚ +SFX Volume 更改音效的音é‡ã€‚ +Player Preference è§ä¸‹é¢ã€‚ + +Player Preference +------------------------------------------------ +Moving Speed ä¸æŒ‰shift时的移动速度。 +Precise Moving Speed 按ä½shift时的移动速度。 +Clear Range Bonus 在æ¯å…³å¼€å§‹æ—¶èŽ·å¾—更多CLR。 +Clear Range Mode 更改CLR的模å¼ã€‚ +Ability Point 如果该数值超过10000ï¼Œä½ æ— æ³•ä¿å˜æ¤é¡µçš„设置。 + +命令行选项 +------------------------------------------------------------------------------------ +是的,它还接å—命令行选项ï¼ï¼ˆè€Œä¸”它们ä¸æœ‰äº›è¿˜å¯èƒ½æ¯”较有用…) +å¦‚æžœä½ è°ƒæ•´äº†è®¾ç½®åŽæ— 法è¿è¡Œäº†ï¼Œä½ å¯ä»¥ç”¨å®ƒä»¬æ¥è¦†ç›–ä½ çš„è®¾ç½®ã€‚ +但是它们ä¸ä¸€äº›å¯èƒ½å¯¼è‡´å¥‡æ€ªçš„行为或者崩溃。所以请å°å¿ƒä½¿ç”¨ã€‚ +ä¸åˆæ³•çš„å‚æ•°å¯èƒ½ä¼šå¯¼è‡´ä¸å¸Œæœ›å¾—到的结果(例如--start+ä¸åˆé€‚çš„å‚数) +它们本æ¥åªåº”è¯¥ç”¨äºŽè°ƒè¯•ç›®çš„ã€‚ä½†æ˜¯å¦‚æžœä½ è¦ç”¨å®ƒä»¬æ¥ä½œå¼Šï¼Œä¹Ÿæ²¡äººå对… +如果ä¸å¸¦ä»»ä½•å‚æ•°è¿è¡Œï¼Œæ¸¸æˆä¼šä»¥æ£å¸¸æ¨¡å¼å¯åŠ¨ã€‚ +其他情况的è¯ã€‚。。: +--help 输出命令行用法并退出。 +--version 输出版本信æ¯å¹¶é€€å‡ºã€‚ +--start=x,y 直接从xå…³y部分开始自由模å¼çš„游æˆã€‚这个部分必须åˆæ³•ã€‚ +--nosound å¼ºåˆ¶æ— å£°ã€‚ +--fullscreen=1/0 强制使用全å±/窗å£æ¨¡å¼ã€‚指定该选项åŽï¼Œç›´æŽ¥æ— 视blr.cfgä¸çš„å…¨å±é€‰é¡¹ã€‚ +--vidmode=0~4 强制使用指定的窗å£å°ºå¯¸ã€‚ + 0 800x600 (原生大å°) + 1 640x480 + 2 960x720 + 3 1024x768 + 4 1280x960 +--firststartup å‡å®šæ˜¯ç¬¬ä¸€æ¬¡è¿è¡Œã€‚如果分数记录文件å˜åœ¨çš„è¯å®ƒä¼šè¢«ä¿ç•™ã€‚ +--fast 「高速ã€æ¨¡å¼ã€‚所有关å¡éƒ½ä¼šå˜çŸä¸¤å€ã€‚ +--logfile=... 使用指定的日志文件å。 +--nohideconsole ä¸éšè—命令行输出窗å£ã€‚(仅é™Windows版本。) + +关于作者 +------------------------------------------------------------------------------------ +-Senseless(this word has multiple means...) +-Often know nothing to do next. If I accidently got it, I would do it at once. +(slowly, though) +-「The perfect balance of code length and efficiency 〠+-One of those "who (like to) live on the edge". --according to Debian maintainers. +-Strange (as many people say) + +这是我第一次(或者是第二次?)æžè¿™ä¹ˆå¤§çš„一个工程。所以这次与其说是写一个游æˆï¼Œè¿˜ä¸å¦‚说åªæ˜¯å†™äº†ä¸€ä¸ª +“框架â€ã€‚但是,这个“框架â€åˆ°çŽ°åœ¨çœ‹èµ·æ¥è¿˜éžå¸¸ä¸å®Œæ•´ã€‚所有东西都还是代ç â€¦ï¼ˆæˆ–è®¸è¿™æ ·ä¹Ÿç®—æ˜¯ä¸€ç§ã€Œæ¡†æž¶ã€ï¼Ÿï¼‰ + +好å§ï¼Œæœ‰ä¸€å¤©è´´å›¾ç”šè‡³éƒ½ä¼šå˜æˆä»£ç 了…到那时贴图会在åˆå§‹åŒ–时被现画到内å˜é‡Œâ€¦ + +åŽ†å² +------------------------------------------------------------------------------------ +这个工程本æ¥åªæ˜¯ä½œä¸ºä¸€ä¸ªBulletLabçš„hge&C++é‡å†™å¼€å§‹çš„。 +ç”±äºŽæœªçŸ¥çš„åŽŸå› ï¼Œå®ƒè¶Šæ¥è¶Šå¤§ï¼Œç”šè‡³éƒ½æ”¹å˜äº†hgeçš„æ ¸å¿ƒã€‚ +å·¥ç¨‹å¼€å§‹å‡ ä¸ªæœˆåŽï¼ŒBLRI(The Creature of Colour)å‘布了。 + +当BLRIå¿«è¦å®Œæˆçš„时候,BLRII从BLRIä¸fork了出æ¥ã€‚ +当时在BLRI代ç çš„åŸºç¡€ä¸Šå»ºç«‹äº†å‡ ä¸ªæµ‹è¯•ç‰ˆæœ¬ã€‚ +åŽæ¥é¢„å‘å¸ƒç‰ˆå»ºç«‹äº†ï¼Œå‡ ä¹Žæ‰€æœ‰æ¥è‡ªBLRI的代ç éƒ½è¢«åˆ æŽ‰äº†ã€‚ +现在它达到了一个我从未期望它能达到的阶段… + +简çŸçš„ç‰ˆæœ¬åŽ†å² +------------------------------------------------------------------------------------ +ChangeLog包å«äº†è¯¥å·¥ç¨‹çš„全部历å²ã€‚ +这里是一个「里程碑ã€çš„列表。 +0.9.9-0 (r99) +最终的候选版本。完æˆäº†æ•´ä¸ªæ¸¸æˆç³»ç»Ÿã€‚ +ä¿®å¤äº†å¤§éƒ¨åˆ†çš„bug。 + +0.9.1-1_PR (r86) +当å‰çš„公开版本。已ç»åŒ…å«äº†æ‰€æœ‰ä¼šå‡ºçŽ°åœ¨æœ€ç»ˆç‰ˆæœ¬é‡Œçš„å…³å¡ã€‚ +èœå•é‡å†™å®Œæˆã€‚ +“å€æ•°ç³»ç»Ÿâ€ç»ˆäºŽèƒ½æ£å¸¸å·¥ä½œäº†ã€‚ + +0.7.3-0_PR (b73) +包å«7个关å¡ã€‚ +众多问题修å¤ï¼ŒWindows版基本稳定了。 +代ç å‘生了巨大的å˜åŒ–。 + +0.4.4-0_PRG (b37a) +包å«4个多一点的关å¡ã€‚ +ä¿®æ£äº†ä¸€éƒ¨åˆ†é—®é¢˜ã€‚ + +0.2.9-1_PR (b21) +第一个公开版,包å«ä¸¤ä¸ªå®Œæ•´çš„å…³å¡ã€‚ +åˆæ¬¡å‡ºçŽ°äº†â€œå€æ•°â€ç³»ç»Ÿï¼Œä½†æ˜¯æ²¡æœ‰å®žé™…作用。 + +0.1.7-2_PR (b16) +第一关完æˆã€‚ + +TB130907 (b10) +激光实现é‡å†™ã€‚ + +TB130827 (b8) +最早的支æŒâ€œæ¿€å…‰â€çš„版本。 + +TB130620~TB130818 (b1~b7) +æ·»åŠ æ–°çš„â€œå¡”â€å’Œå…³å¡ã€‚ + +TB130610 (b0) +试验版本建立。 diff --git a/archive/blr2/VERSION b/archive/blr2/VERSION new file mode 100755 index 0000000..9f8cf97 --- /dev/null +++ b/archive/blr2/VERSION @@ -0,0 +1 @@ +1.0.0-0 (r101)
\ No newline at end of file diff --git a/archive/blr2/resources/b_diff.png b/archive/blr2/resources/b_diff.png Binary files differnew file mode 100755 index 0000000..400cac9 --- /dev/null +++ b/archive/blr2/resources/b_diff.png diff --git a/archive/blr2/resources/b_inter.png b/archive/blr2/resources/b_inter.png Binary files differnew file mode 100644 index 0000000..00976a5 --- /dev/null +++ b/archive/blr2/resources/b_inter.png diff --git a/archive/blr2/resources/b_leaves.png b/archive/blr2/resources/b_leaves.png Binary files differnew file mode 100755 index 0000000..6bd4a8b --- /dev/null +++ b/archive/blr2/resources/b_leaves.png diff --git a/archive/blr2/resources/b_null.png b/archive/blr2/resources/b_null.png Binary files differnew file mode 100755 index 0000000..7c60dce --- /dev/null +++ b/archive/blr2/resources/b_null.png diff --git a/archive/blr2/resources/bdig.fnt b/archive/blr2/resources/bdig.fnt new file mode 100644 index 0000000..453c492 --- /dev/null +++ b/archive/blr2/resources/bdig.fnt @@ -0,0 +1,15 @@ +[HGEFONT] + +Bitmap=credits.png + +Char="-",340,354,23,33,0,0 +Char="0",6,354,30,33,0,0 +Char="1",46,354,14,33,0,0 +Char="2",72,354,29,33,0,0 +Char="3",105,354,29,33,0,0 +Char="4",140,354,26,33,0,0 +Char="5",171,354,28,33,0,0 +Char="6",204,354,29,33,0,0 +Char="7",238,354,27,33,0,0 +Char="8",269,354,31,33,0,0 +Char="9",302,354,31,33,0,0 diff --git a/archive/blr2/resources/blnsns.png b/archive/blr2/resources/blnsns.png Binary files differnew file mode 100755 index 0000000..ae8f7d4 --- /dev/null +++ b/archive/blr2/resources/blnsns.png diff --git a/archive/blr2/resources/charmap.fnt b/archive/blr2/resources/charmap.fnt new file mode 100755 index 0000000..f31840d --- /dev/null +++ b/archive/blr2/resources/charmap.fnt @@ -0,0 +1,99 @@ +[HGEFONT]
+
+Bitmap=blnsns.png
+
+Char=" ",1,1,3,36,-1,7
+Char="!",5,1,6,36,1,1
+Char=""",12,1,10,36,0,0
+Char="#",23,1,24,36,0,-1
+Char="$",48,1,15,36,0,-1
+Char="%",64,1,25,36,0,0
+Char="&",90,1,23,36,0,0
+Char="'",114,1,5,36,0,1
+Char="(",120,1,12,36,1,-1
+Char=")",133,1,12,36,-1,1
+Char="*",146,1,13,36,0,-1
+Char="+",160,1,15,36,-1,0
+Char=",",176,1,9,36,-1,0
+Char="-",186,1,13,36,0,0
+Char=".",200,1,7,36,0,0
+Char="/",208,1,10,36,0,0
+Char="0",219,1,20,36,0,0
+Char="1",240,1,9,36,11,0
+Char="2",250,1,16,36,4,0
+Char="3",267,1,16,36,4,0
+Char="4",284,1,18,36,2,0
+Char="5",303,1,17,36,3,0
+Char="6",321,1,17,36,3,0
+Char="7",339,1,17,36,3,0
+Char="8",357,1,17,36,3,0
+Char="9",375,1,17,36,3,0
+Char=":",393,1,7,36,0,0
+Char=";",401,1,9,36,-2,0
+Char="<",411,1,13,36,0,-1
+Char="=",425,1,15,36,0,0
+Char=">",441,1,12,36,0,0
+Char="?",454,1,15,36,-1,0
+Char="@",470,1,20,36,0,1
+Char="A",1,38,24,36,-1,-1
+Char="B",26,38,20,36,1,0
+Char="C",47,38,21,36,0,-1
+Char="D",69,38,22,36,1,0
+Char="E",92,38,17,36,1,0
+Char="F",110,38,17,36,1,0
+Char="G",128,38,23,36,0,0
+Char="H",152,38,22,36,1,1
+Char="I",175,38,6,36,1,1
+Char="J",182,38,9,36,-1,1
+Char="K",192,38,20,36,1,-1
+Char="L",213,38,17,36,1,0
+Char="M",231,38,25,36,1,1
+Char="N",257,38,22,36,1,1
+Char="O",280,38,25,36,0,0
+Char="P",306,38,20,36,1,0
+Char="Q",327,38,25,36,0,0
+Char="R",353,38,19,36,1,0
+Char="S",373,38,15,36,1,0
+Char="T",389,38,18,36,0,-1
+Char="U",408,38,20,36,1,1
+Char="V",429,38,21,36,0,0
+Char="W",451,38,30,36,0,0
+Char="X",482,38,20,36,0,-1
+Char="Y",1,75,20,36,0,0
+Char="Z",22,75,19,36,-1,-1
+Char="[",42,75,11,36,2,-1
+Char="\",54,75,10,36,0,0
+Char="]",65,75,11,36,-1,2
+Char="^",77,75,17,36,-1,0
+Char="_",95,75,17,36,-1,-1
+Char="`",113,75,11,36,0,1
+Char="a",125,75,19,36,0,0
+Char="b",145,75,17,36,1,1
+Char="c",163,75,13,36,0,1
+Char="d",177,75,18,36,0,1
+Char="e",196,75,15,36,0,1
+Char="f",212,75,12,36,-1,-1
+Char="g",225,75,17,36,0,1
+Char="h",243,75,16,36,1,1
+Char="i",260,75,7,36,1,0
+Char="j",268,75,9,36,-2,1
+Char="k",278,75,17,36,1,1
+Char="l",296,75,6,36,1,1
+Char="m",303,75,29,36,0,1
+Char="n",333,75,17,36,0,1
+Char="o",351,75,17,36,0,0
+Char="p",369,75,18,36,0,1
+Char="q",388,75,19,36,0,0
+Char="r",408,75,12,36,0,-1
+Char="s",421,75,9,36,0,1
+Char="t",431,75,12,36,-1,1
+Char="u",444,75,17,36,1,1
+Char="v",462,75,17,36,0,1
+Char="w",480,75,26,36,0,-1
+Char="x",1,112,14,36,0,1
+Char="y",16,112,15,36,0,1
+Char="z",32,112,14,36,0,0
+Char="{",47,112,13,36,0,-1
+Char="|",61,112,5,36,2,1
+Char="}",67,112,12,36,0,0
+Char="~",80,112,18,36,0,-1
diff --git a/archive/blr2/resources/credits.png b/archive/blr2/resources/credits.png Binary files differnew file mode 100755 index 0000000..d647d86 --- /dev/null +++ b/archive/blr2/resources/credits.png diff --git a/archive/blr2/resources/e_leaf.png b/archive/blr2/resources/e_leaf.png Binary files differnew file mode 100755 index 0000000..d64d6ca --- /dev/null +++ b/archive/blr2/resources/e_leaf.png diff --git a/archive/blr2/resources/e_sflake.png b/archive/blr2/resources/e_sflake.png Binary files differnew file mode 100644 index 0000000..963d85e --- /dev/null +++ b/archive/blr2/resources/e_sflake.png diff --git a/archive/blr2/resources/e_skyitem.png b/archive/blr2/resources/e_skyitem.png Binary files differnew file mode 100644 index 0000000..e3e168b --- /dev/null +++ b/archive/blr2/resources/e_skyitem.png diff --git a/archive/blr2/resources/help.png b/archive/blr2/resources/help.png Binary files differnew file mode 100644 index 0000000..32718ee --- /dev/null +++ b/archive/blr2/resources/help.png diff --git a/archive/blr2/resources/menus.png b/archive/blr2/resources/menus.png Binary files differnew file mode 100644 index 0000000..9ce0aba --- /dev/null +++ b/archive/blr2/resources/menus.png diff --git a/archive/blr2/resources/ss.png b/archive/blr2/resources/ss.png Binary files differnew file mode 100755 index 0000000..e34abbb --- /dev/null +++ b/archive/blr2/resources/ss.png diff --git a/archive/blr2/resources/tap.ogg b/archive/blr2/resources/tap.ogg Binary files differnew file mode 100755 index 0000000..1ef00b0 --- /dev/null +++ b/archive/blr2/resources/tap.ogg diff --git a/archive/blr2/resources/title.png b/archive/blr2/resources/title.png Binary files differnew file mode 100644 index 0000000..f0801ef --- /dev/null +++ b/archive/blr2/resources/title.png diff --git a/archive/blr2/resources/vdig.fnt b/archive/blr2/resources/vdig.fnt new file mode 100644 index 0000000..6d89742 --- /dev/null +++ b/archive/blr2/resources/vdig.fnt @@ -0,0 +1,20 @@ +[HGEFONT] + +Bitmap=credits.png + +Char=" ",541,279,1,50,33,5 +Char="(",326,278,23,61,0,0 +Char=")",354,278,23,60,0,0 +Char="-",512,279,29,50,0,0 +Char=".",483,279,7,50,13,14 +Char="0",244,222,42,50,0,0 +Char="1",305,222,15,50,0,0 +Char="2",341,222,39,50,0,0 +Char="3",389,222,39,50,0,0 +Char="4",440,222,34,50,0,0 +Char="5",485,222,39,50,0,0 +Char="6",533,222,39,50,0,0 +Char="7",248,279,34,50,0,0 +Char="8",383,279,43,50,0,0 +Char="9",433,279,39,50,0,0 +Char="r",293,279,29,50,0,0 diff --git a/archive/blr2/src/background.h b/archive/blr2/src/background.h new file mode 100644 index 0000000..849438c --- /dev/null +++ b/archive/blr2/src/background.h @@ -0,0 +1,574 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Background drawing Implementations +// Copyright Chrisoft 2014 +#include <list> +const char* BACKGROUND_H_FN="background.h"; + +double deltaBG; +//******************************************** +//Full-screen Leaves Background +//******************************************** +class BG_Leaves +{ +private: + DWORD alpha,alim; + bool onfadein,onfadeout; + int fadebreak; + hgeSprite* BGSpr; + HTEXTURE LeafTex; + void DoFadeIn() + { + if (LOWFPS)fadebreak+=17;else ++fadebreak; + if (fadebreak>17)fadebreak=0;else return; + if (LOWFPS)if(alpha+0x20<=alim)alpha+=0x20;else{} + else if (alpha+0x2<=alim)alpha+=2; + if (alpha>=alim)onfadein=false; + } + void DoFadeOut() + { + if (LOWFPS)fadebreak+=17;else ++fadebreak; + if (fadebreak>30)fadebreak=0;else return; + if (LOWFPS) + if (alpha<0x20)alpha=0;else alpha-=0x20; + else + if (alpha<0x2)alpha=0;else alpha-=0x2; + if (!alpha)onfadeout=0; + } +public: + bool IsActive() + { + return alpha?true:false; + } + void Init(DWORD limalpha) + { + LeafTex=hge->Texture_Load("./Resources/b_leaves.png"); + BGSpr=new hgeSprite(LeafTex,0,0,200,150); + BGSpr->SetColor(0x00CCCCCC); + onfadein=onfadeout=false;alpha=0x00;alim=limalpha;fadebreak=0; + + } + void SetFadeIn() + { + alpha=0x01; + onfadein=true; + } + void SetFadeOut() + { + alpha=alim; + onfadeout=true; + } + void Update() + { + double tx,ty,dt; + if (onfadein)DoFadeIn(); + if (onfadeout)DoFadeOut(); + dt=hge->Timer_GetDelta(); + deltaBG+=dt; + tx=200*cosf(deltaBG/10); + ty=150*sinf(deltaBG/10); + BGSpr->SetColor(ARGB(alpha,0xCC,0xCC,0xCC)); + for (int i=-1;i<5;++i) + for (int j=-1;j<5;++j) + BGSpr->Render(i*199.0f+tx,j*149.0f+ty); + } +}; +BG_Leaves Leaves; +//******************************************** +//Animated Leaves Background +//******************************************** +HTEXTURE TLeaf; +HTEXTURE TSflake; +bool LE_Active; +double lescale; +HTEXTURE letex;TextureRect letr; +DWORD lecolor; +class Leaf_Node +{ +private: + hgeSprite* Leaf; + double Rotation,DRotate; + double x,y,dx,dy; +public: + void init() + { + Leaf=new hgeSprite(letex,letr.x,letr.y,letr.w,letr.h); + Leaf->SetColor(lecolor); + x=rand()%908-108;y=-108; + dx=rand()%200/100.0f-1.0f;dx*=0.075; + dy=rand()%200/100.0f+0.5f;dy*=0.075; + Rotation=0;DRotate=rand()%100/10000.0f;DRotate*=0.1; + } + bool Update() + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + { + Rotation+=DRotate; + x+=dx;y+=dy; + } + if (x>908||x<-108||y>708)return 1; + Leaf->RenderEx(x,y,Rotation,lescale); + return 0; + } +}; +class Leaf_Anim +{ +public: + std::list<Leaf_Node> llist; + double brk; + void Init() + { + llist.clear(); + brk=rand()%1000/1250.0f; + } + void Update() + { + brk-=hge->Timer_GetDelta(); + if(brk<0) + { + brk=rand()%1000/1250.0f; + Leaf_Node a;a.init(); + llist.push_back(a); + } + for(std::list<Leaf_Node>::iterator i=llist.begin();i!=llist.end();++i) + { + if(i->Update()) + { + std::list<Leaf_Node>::iterator r=i;++r; + llist.erase(i);i=--r; + } + } + } +}Leaf; +//******************************************** +//3D-sky Background +//Based on a hge tutorial +//******************************************** +static const DWORD skyTopColors[3] = {0xFF15092A, 0xFF6C6480, 0xFF89B9D0}; +static const DWORD skyBtmColors[3] = {0xFF303E57, 0xFFAC7963, 0xFFCAD7DB}; +static const DWORD seaTopColors[3] = {0xFF3D546B, 0xFF927E76, 0xFF86A2AD}; +static const DWORD seaBtmColors[3] = {0xFF1E394C, 0xFF2F4E64, 0xFF2F4E64}; +static const int skyseq[9]={0, 0, 1, 2, 2, 2, 1, 0, 0}; +class TDSky +{ +#define ScreenWidth 800 +#define ScreenHeight 600 +#define Stars 100 +#define SeaDisize 16 +#define SkyHeight (ScreenHeight*0.6f) +#define StarsHeight (SkyHeight*0.9f) +#define OrbitRadius (ScreenWidth*0.43f) +private: + HTEXTURE skyitem; + hgeQuad skygrad; + hgeSprite *sun,*moon,*glow,*seaglow,*star; + hgeDistortionMesh *sea,*skylyr; + float timet,speed,skya,skylima,seq_residue; + int seq_id; + float starX[Stars],starY[Stars],starS[Stars],starA[Stars],seaP[SeaDisize]; + hgeColor colWhite,colSkyTop,colSkyBtm,colSeaTop,colSeaBtm; + hgeColor colSun,colSunGlow; + hgeColor colMoon,colMoonGlow,colSeaGlow; + float sunX,sunY,sunS,sunGlowS; + float moonX,moonY,moonS,moonGlowS; + float seaGlowX,seaGlowSX,seaGlowSY; + bool skyOnFadeIn,skyOnFadeOut; + float GetTime() + { + struct tm *t=0; + time_t tt=time(NULL); + t=localtime(&tt); + float tmp=0; + if(t) + { + tmp=t->tm_sec; + tmp=t->tm_min+tmp/60.0f; + tmp=t->tm_hour+tmp/60.0f; + } + return tmp; + } + void SkyDoFadeIn() + { + float dlt=1.0f/hge->Timer_GetFPS(); + if (skya+dlt<skylima)skya+=dlt; + else skya=skylima,skyOnFadeIn=false; + } + void SkyDoFadeOut() + { + float dlt=1.0f/hge->Timer_GetFPS(); + if (skya-dlt>0)skya-=dlt; + else skya=0.0f,skyOnFadeOut=false; + } +public: + bool Init() + { + skyitem=hge->Texture_Load("./Resources/e_skyitem.png"); + if(!skyitem) return false; + skygrad.tex=0;skygrad.blend=BLEND_DEFAULT; + for(int i=0;i<4;++i)skygrad.v[i].z=0.5; + skygrad.v[0].tx=0;skygrad.v[0].ty=0; + skygrad.v[1].tx=1;skygrad.v[1].ty=0; + skygrad.v[2].tx=1;skygrad.v[2].ty=1; + skygrad.v[3].tx=0;skygrad.v[3].ty=1; + skygrad.v[0].x=0;skygrad.v[0].y=0; + skygrad.v[1].x=800;skygrad.v[1].y=0; + skygrad.v[2].x=800;skygrad.v[2].y=600; + skygrad.v[3].x=0;skygrad.v[3].y=600; + sea=new hgeDistortionMesh(SeaDisize, SeaDisize); + sea->SetTextureRect(0, 0, ScreenWidth, ScreenHeight-SkyHeight); + sun=new hgeSprite(skyitem,81,0,114,114); + sun->SetHotSpot(57,57); + moon=new hgeSprite(skyitem,0,0,81,81); + moon->SetHotSpot(40,40); + star=new hgeSprite(skyitem,195,0,9,9); + star->SetHotSpot(5,5); + glow=new hgeSprite(skyitem,204,0,128,128); + glow->SetHotSpot(64,64); + glow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND | BLEND_NOZWRITE); + seaglow=new hgeSprite(skyitem,204,96,128,32); + seaglow->SetHotSpot(64,0); + seaglow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHAADD | BLEND_NOZWRITE); + skylyr=new hgeDistortionMesh(16, 16); + skylyr->SetTexture(skyitem); + skylyr->SetTextureRect(0,128,512,512); + skylyr->SetBlendMode(BLEND_ALPHAADD); + colWhite.SetHWColor(0xFFFFFFFF); + timet=GetTime(); + speed=skya=0.0f; + for(int i=0;i<Stars;++i) + { + starX[i]=rand()%ScreenWidth; + starY[i]=rand()%((int)StarsHeight); + starS[i]=(rand()%60+10.0f)/100.0f; + } + for(int i=0;i<SeaDisize;++i) + { + seaP[i]=i+(rand()%300-150.0f)/10.0f; + } + return true; + } + void Deinit() + { + delete seaglow;delete glow; + delete star;delete moon; + delete sun; + delete sea;delete skylyr; + hge->Texture_Free(skyitem); + } + void SetSpeed(float _speed){speed=_speed;} + void SetSkyA(float _skya){skya=_skya;} + void SetTime(float _timet){timet=_timet;} + void SkySetFadeIn(float _starta=0.0f,float _lima=1.0f) + { + skya=_starta;skylima=_lima; + skyOnFadeIn=true;skyOnFadeOut=false; + } + void SkySetFadeOut(float _starta=0.0f) + { + if (_starta>1E-4)skya=_starta; + skyOnFadeIn=false;skyOnFadeOut=true; + } + void Update() + { + int i, j, k; + float zenith,a,dy,fTime; + float posX,s1,s2; + const float cellw=ScreenWidth/(SeaDisize-1); + hgeColor col1,col2; + DWORD dwCol1,dwCol2; + if(speed==0.0f) timet=GetTime(); + else + { + timet+=hge->Timer_GetDelta()*speed; + if(timet>=24.0f) timet-=24.0f; + } + seq_id=(int)(timet/3); + seq_residue=timet/3-seq_id; + zenith=-(timet/12.0f*pi-pi/2.0f); + col1.SetHWColor(skyTopColors[skyseq[seq_id]]); + col2.SetHWColor(skyTopColors[skyseq[seq_id+1]]); + colSkyTop=col2*seq_residue + col1*(1.0f-seq_residue); + col1.SetHWColor(skyBtmColors[skyseq[seq_id]]); + col2.SetHWColor(skyBtmColors[skyseq[seq_id+1]]); + colSkyBtm=col2*seq_residue + col1*(1.0f-seq_residue); + col1.SetHWColor(seaTopColors[skyseq[seq_id]]); + col2.SetHWColor(seaTopColors[skyseq[seq_id+1]]); + colSeaTop=col2*seq_residue + col1*(1.0f-seq_residue); + col1.SetHWColor(seaBtmColors[skyseq[seq_id]]); + col2.SetHWColor(seaBtmColors[skyseq[seq_id+1]]); + colSeaBtm=col2*seq_residue + col1*(1.0f-seq_residue); + if(seq_id>=6 || seq_id<2) + for(int i=0; i<Stars; ++i) + { + a=1.0f-starY[i]/StarsHeight; + //a*=hge->Random_Float(0.6f, 1.0f); + a*=(rand()%40+60.0f)/100.0f; + if(seq_id>=6) a*=sinf((timet-18.0f)/12.0f*pi); + else a*=sinf((1.0f-timet/6.0f)*pi/2); + starA[i]=a; + } + if(seq_id==2) a=sinf(seq_residue*pi/2); + else if(seq_id==5) a=cosf(seq_residue*pi/2); + else if(seq_id>2 && seq_id<5) a=1.0f; + else a=0.0f; + colSun.SetHWColor(0xFFEAE1BE); + colSun=colSun*(1-a)+colWhite*a; + a=(cosf(timet/6.0f*pi)+1.0f)/2.0f; + if(seq_id>=2 && seq_id<=6) + { + colSunGlow=colWhite*a; + colSunGlow.a=1.0f; + } + else colSunGlow.SetHWColor(0xFF000000); + sunX=ScreenWidth*0.5f+cosf(zenith)*OrbitRadius; + sunY=SkyHeight*1.2f+sinf(zenith)*OrbitRadius; + sunS=1.0f-0.3f*sinf((timet-6.0f)/12.0f*pi); + sunGlowS=3.0f*(1.0f-a)+3.0f; + if(seq_id>=6) a=sinf((timet-18.0f)/12.0f*pi); + else a=sinf((1.0f-timet/6.0f)*pi/2); + colMoon.SetHWColor(0x20FFFFFF); + colMoon=colMoon*(1-a)+colWhite*a; + colMoonGlow=colWhite; + colMoonGlow.a=0.5f*a; + moonX=ScreenWidth*0.5f+cosf(zenith-pi)*OrbitRadius; + moonY=SkyHeight*1.2f+sinf(zenith-pi)*OrbitRadius; + moonS=1.0f-0.3f*sinf((timet+6.0f)/12.0f*pi); + moonGlowS=a*0.4f+0.5f; + if(timet>19.0f || timet<4.5f) + { + a=0.2f; + if(timet>19.0f && timet<20.0f) a*=(timet-19.0f); + else if(timet>3.5f && timet<4.5f) a*=1.0f-(timet-3.5f); + colSeaGlow=colMoonGlow; + colSeaGlow.a=a; + seaGlowX=moonX; + seaGlowSX=moonGlowS*3.0f; + seaGlowSY=moonGlowS*2.0f; + } + else if(timet>6.5f && timet<19.0f) + { + a=0.3f; + if(timet<7.5f) a*=(timet-6.5f); + else if(timet>18.0f) a*=1.0f-(timet-18.0f); + colSeaGlow=colSunGlow; + colSeaGlow.a=a; + seaGlowX=sunX; + seaGlowSX=sunGlowS; + seaGlowSY=sunGlowS*0.6f; + } + else colSeaGlow.a=0.0f; + for(i=1; i<SeaDisize-1; ++i) + { + a=float(i)/(SeaDisize-1); + col1=colSeaTop*(1-a)+colSeaBtm*a; + dwCol1=col1.GetHWColor(); + fTime=2.0f*hge->Timer_GetTime(); + a*=20; + for(j=0; j<SeaDisize; ++j) + { + sea->SetColor(j, i, dwCol1); + dy=a*sinf(seaP[i]+(float(j)/(SeaDisize-1)-0.5f)*pi*16.0f-fTime); + sea->SetDisplacement(j, i, 0.0f, dy, HGEDISP_NODE); + } + } + float t=0.1*hge->Timer_GetTime(); + skylyr->SetTextureRect(128+sin(t)*128.0f,256+cos(t)*128.0f,256,128); + if (skyOnFadeIn)SkyDoFadeIn(); + if (skyOnFadeOut)SkyDoFadeOut(); + for (int i=-8;i<8;++i) + for (int j=-8;j<8;++j) + { + skylyr->SetColor(j+8,i+8,ARGB((int)(skya*((i+9)*16-16)),0xFF,0xFF,0xFF)); + skylyr->SetDisplacement(j+8,i+8,j*(16.0f*((i+9)/16.0f)+64.0f),i*24,HGEDISP_CENTER); + } + dwCol1=colSeaTop.GetHWColor(); + dwCol2=colSeaBtm.GetHWColor(); + for(j=0; j<SeaDisize; ++j) + { + sea->SetColor(j, 0, dwCol1); + sea->SetColor(j, SeaDisize-1, dwCol2); + } + if(timet>19.0f || timet<5.0f) + { + a=0.12f; + if(timet>19.0f && timet<20.0f) a*=(timet-19.0f); + else if(timet>4.0f && timet<5.0f) a*=1.0f-(timet-4.0f); + posX=moonX; + } + else if(timet>7.0f && timet<17.0f) + { + a=0.14f; + if(timet<8.0f) a*=(timet-7.0f); + else if(timet>16.0f) a*=1.0f-(timet-16.0f); + posX=sunX; + } + else a=0.0f; + if(a!=0.0f) + { + k=(int)floorf(posX/cellw); + s1=(1.0f-(posX-k*cellw)/cellw); + s2=(1.0f-((k+1)*cellw-posX)/cellw); + if(s1>0.7f) s1=0.7f; + if(s2>0.7f) s2=0.7f; + s1*=a;s2*=a; + for(i=0; i<SeaDisize; i+=2) + { + a=sinf(float(i)/(SeaDisize-1)*pi/2); + col1.SetHWColor(sea->GetColor(k,i)); + col1+=colSun*s1*(1-a); + col1.Clamp(); + sea->SetColor(k, i, col1.GetHWColor()); + col1.SetHWColor(sea->GetColor(k+1,i)); + col1+=colSun*s2*(1-a); + col1.Clamp(); + sea->SetColor(k+1, i, col1.GetHWColor()); + } + } + } + void Render() + { +#ifdef WIN32 + skygrad.tex=0; + skygrad.blend=BLEND_DEFAULT; +#endif + skygrad.v[0].col=skygrad.v[1].col=colSkyTop.GetHWColor(); + skygrad.v[2].col=skygrad.v[3].col=colSkyBtm.GetHWColor(); + hge->Gfx_RenderQuad(&skygrad); + if(seq_id>=6 || seq_id<2) + for(int i=0; i<Stars; ++i) + { + star->SetColor((DWORD(starA[i]*255.0f)<<24) | 0xFFFFFF); + star->RenderEx(starX[i], starY[i], 0.0f, starS[i]); + } + glow->SetColor(colSunGlow.GetHWColor()); + glow->RenderEx(sunX, sunY, 0.0f, sunGlowS); + sun->SetColor(colSun.GetHWColor()); + sun->RenderEx(sunX, sunY, 0.0f, sunS); + glow->SetColor(colMoonGlow.GetHWColor()); + glow->RenderEx(moonX, moonY, 0.0f, moonGlowS); + moon->SetColor(colMoon.GetHWColor()); + moon->RenderEx(moonX, moonY, 0.0f, moonS); + sea->Render(0, SkyHeight); + seaglow->SetColor(colSeaGlow.GetHWColor()); + seaglow->RenderEx(seaGlowX, SkyHeight, 0.0f, seaGlowSX, seaGlowSY); + skylyr->Render(ScreenWidth/8*3,ScreenHeight/3*2); + } +}; +TDSky sky; +bool skyactive; + +class PicBack +{ +public: + enum arMode + { + Centered, + Tiled, + Stretched + }; +private: + hgeQuad quad; + arMode Mode; + DWORD alpha,alim; + bool onfadein,onfadeout; + int fadebreak; + double scale; + void DoFadeIn() + { + if (LOWFPS)fadebreak+=17;else ++fadebreak; + if (fadebreak>17)fadebreak=0;else return; + if (LOWFPS)if(alpha+0x20<=alim)alpha+=0x20;else alpha=alim; + else if (alpha+0x2<=alim)alpha+=2;else alpha=alim; + if (alpha>=alim)onfadein=false; + } + void DoFadeOut() + { + if (LOWFPS)fadebreak+=17;else ++fadebreak; + if (fadebreak>17)fadebreak=0;else return; + if (LOWFPS)if (alpha<0x20)alpha=0;else alpha-=0x20; + else if (alpha<0x2)alpha=0;else alpha-=0x2; + if (!alpha)onfadeout=false; + } + void RenderCenterAt(vector2d a,double scl) + { + vector2d s=vector2d(hge->Texture_GetWidth(quad.tex,true)*scl,hge->Texture_GetHeight(quad.tex,true)*scl); + for(int i=0;i<4;++i)quad.v[i].col=SETA(0xFFFFFF,alpha); + quad.v[0].x=a.x-s.x/2.0f;quad.v[0].y=a.y-s.y/2.0f; + quad.v[1].x=a.x+s.x/2.0f;quad.v[1].y=a.y-s.y/2.0f; + quad.v[2].x=a.x+s.x/2.0f;quad.v[2].y=a.y+s.y/2.0f; + quad.v[3].x=a.x-s.x/2.0f;quad.v[3].y=a.y+s.y/2.0f; + hge->Gfx_RenderQuad(&quad); + } +public: + bool active(){return alpha;} + void SetScale(double _scl){scale=_scl;} + void Init(const char *tx,arMode _Mode,DWORD _alim) + { + quad.tex=hge->Texture_Load(tx);alim=_alim; + Mode=_Mode;scale=1;quad.blend=BLEND_DEFAULT; +#ifdef WIN32 + vector2d srl=vector2d(hge->Texture_GetWidth(quad.tex,true), + hge->Texture_GetHeight(quad.tex,true)); + vector2d srm=vector2d(hge->Texture_GetWidth(quad.tex,false), + hge->Texture_GetHeight(quad.tex,false)); + srm.x=srl.x/srm.x;srm.y=srl.y/srm.y; + quad.v[0].tx=0;quad.v[0].ty=0; + quad.v[1].tx=srm.x;quad.v[1].ty=0; + quad.v[2].tx=srm.x;quad.v[2].ty=srm.y; + quad.v[3].tx=0;quad.v[3].ty=srm.y; +#else + quad.v[0].tx=0,quad.v[0].ty=0; + quad.v[1].tx=1,quad.v[1].ty=0; + quad.v[2].tx=1,quad.v[2].ty=1; + quad.v[3].tx=0,quad.v[3].ty=1; +#endif + onfadein=onfadeout=false;alpha=0; + } + void Update() + { + if(onfadein)DoFadeIn();if(onfadeout)DoFadeOut(); + switch(Mode) + { + case Centered: + RenderCenterAt(vector2d(400,300),scale); + break; + case Tiled: + { + vector2d s=vector2d(hge->Texture_GetWidth(quad.tex,true)*scale,hge->Texture_GetHeight(quad.tex,true)*scale); + for(int i=0;i*s.x<=800;++i) + for(int j=0;j*s.y<=600;++j) + RenderCenterAt(vector2d(s.x/2+i*s.x,s.y/2+j*s.y),scale); + } + break; + case Stretched: + for(int i=0;i<4;++i)quad.v[i].col=SETA(0xFFFFFF,alpha); + quad.v[0].x=0,quad.v[0].y=0; + quad.v[1].x=800,quad.v[1].y=0; + quad.v[2].x=800,quad.v[2].y=600; + quad.v[3].x=0,quad.v[3].y=600; + hge->Gfx_RenderQuad(&quad); + break; + } + } + void SetFadeIn() + { + alpha=0x01; + onfadein=true; + } + void SetFadeOut() + { + alpha=alim; + onfadeout=true; + } +}binter,bdiff; +DWORD ColorTransfer(DWORD a,DWORD t) +{ + int r=GETR(a),g=GETG(a),b=GETB(a),sa=GETA(a); + int tr=GETR(t),tg=GETG(t),tb=GETB(t),ta=GETA(t); + if (sa<ta)++sa;if (sa>ta)--sa; + if (r<tr)++r;if (r>tr)--r; + if (g<tg)++g;if (g>tg)--g; + if (b<tb)++b;if (b>tb)--b; + a=SETR(a,r);a=SETG(a,g);a=SETB(a,b);a=SETA(a,sa); + return a; +} diff --git a/archive/blr2/src/effects.h b/archive/blr2/src/effects.h new file mode 100644 index 0000000..d71a445 --- /dev/null +++ b/archive/blr2/src/effects.h @@ -0,0 +1,104 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Effects Implementations +// Copyright Chrisoft 2014 +//static const char* EFFECTS_H_FN="effects.h"; + +void SCEffect_Attatch(vector2d Target=vector2d(-100,-100)) +{ + int cnt=rand()%8+3; + if(Target.x<-50&&Target.y<-50)Target=playerpos; + for (int ii=1;ii<=cnt;++ii) + { + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].bullettype=254; + bullet[i].bulletpos.x=Target.x+3; + bullet[i].bulletpos.y=Target.y+3; + bullet[i].bulletdir.x=rand()%100-50; + bullet[i].bulletdir.y=rand()%100-50; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=rand()%4+2; + bullet[i].sccolor=0x80FFFFFF; + } +} +void SCEffect_Process(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=254)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + ++effskp; + if (effskp==7) + bullet[i].sccolor=bullet[i].sccolor-0x1F000000,effskp=0; + } + else + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + ++effskp; + if (effskp==7) + bullet[i].sccolor=bullet[i].sccolor-0x1000000,effskp=0; + } + } + if (GETA(bullet[i].sccolor)<=0x0A||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + bulletspr[grey]->SetColor(bullet[i].sccolor); + bulletspr[grey]->RenderEx(bullet[i].bulletpos.x+2.4,bullet[i].bulletpos.y+2.4,0,0.2,0); + } +} +void BulletEffect_Attatch(int n) +{ + bullet[n].scale=2; + bullet[n].effbrk=17; +} +void BulletEffect_Process(int n) +{ + if (bullet[n].scale<=1){bullet[n].scale=1;return;} + if (LOWFPS) + bullet[n].effbrk-=17; + else + --bullet[n].effbrk; + if (bullet[n].effbrk<=0) + bullet[n].scale-=0.04,bullet[n].effbrk=17; +} +int BulletEffect_Death(Bullet a,DWORD color) +{ + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].bullettype=253; + bullet[i].bulletpos.x=a.bulletpos.x; + bullet[i].bulletpos.y=a.bulletpos.y; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=bullet[i].dist=0; + bullet[i].bulletspeed=0; + bullet[i].alterColor=circle; + bullet[i].scollable=false; + bullet[i].scale=1; + bullet[i].sccolor=SETA(color,0x80); + bullet[i].effbrk=7; + return i; +} +void BulletDeath_Process(int i) +{ + if (!bullet[i].exist)return; + if (LOWFPS) + bullet[i].effbrk-=17; + else + --bullet[i].effbrk; + if (GETA(bullet[i].sccolor)<=10)return (void)(bullet[i].exist=false); + if (bullet[i].effbrk<=0&&Current_Position==1) + bullet[i].effbrk=7,bullet[i].scale+=0.1,bullet[i].sccolor=SETA(bullet[i].sccolor,GETA(bullet[i].sccolor)-6); + bulletspr[circle]->SetColor(bullet[i].sccolor); + bulletspr[circle]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale); +} diff --git a/archive/blr2/src/global.h b/archive/blr2/src/global.h new file mode 100644 index 0000000..a20c5d1 --- /dev/null +++ b/archive/blr2/src/global.h @@ -0,0 +1,549 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Global varibles and implementations +// Copyright Chrisoft 2014 +#include <hge.h> +#include <hgefont.h> +#define MaxRes 80 +#define Resd 20.0f +#define MaxBulCnt 20000 +HGE *hge=0; +HEFFECT snd,menuin,menuout,menumov; +hgeQuad quad; +hgeFont *fnt,*vdig,*bdig; +hgeSprite *spr,*titlespr; +int Current_Position;//Where we are now +/*Scenes: +0: main menu +1: game scene +2: tip scene +3: start menu +4: about scene +5: death scene +6: complete scene +7: new highscore scene +8: highscore scene +9: highscore view scene +10: highscore details scene +11: Pause scene +12: BackToTitle Confirmation +13: Options scene +14: Player Profile scene +15: Help scene +*/ +HTEXTURE SprSheet,TexTitle,TexCredits,MenuTex,HelpTex; +/* +Texture Mapping: +SprSheet:ss.png +Bullet Blue 0,0,24,24 +Bullet Dark Blue 24,0,24,24 +Bullet Green 48,0,24,24 +Bullet Orange 72,0,24,24 +Bullet Pnt 96,0,24,24 +Bullet Purple 120,0,24,24 +Bullet Red 144,0,24,24 +Bullet White 168,0,24,24 +Bullet Yellow 192,0,24,24 +Cursor 216,0,24,24 +Player 0,24,24,24 +Bullet Circle 24,24,24,24 +Tower Blue 0,48,44,44 +Tower Dark Blue 0,92,44,44 +Tower Green 0,136,44,44 +Tower Orange 0,180,44,44 +Tower Purple 48,24,44,44 +Tower Red 92,24,44,44 +Tower White 136,24,44,44 +Tower Yellow 180,24,44,44 +Target 63,71,193,193 +Laser Module 0,264,248,8 +Ribbon Module 151,264,2,8 +Multiplier"+1" 0,272,48,48 +MultPo spawn efct 48,272,48,48 +Text:blnsns.png +"Multiplier bonus!" 0,235,163,21 +Menus and titles: menus.png +Menu items... +Classic Mode 0,0,256,128 +Assessment Mode 256,0,256,128 +Free Play Mode 0,128,256,128 +Titles... +Select a Mode 256,128,256,64 +Options 256,192,256,64 +Player Preference 0,256,256,64 +You Are Dead! 256,256,256,64 +It Ends Here! 0,320,256,64 +View Highscore for..0,376,256,64 +Highscore details 0,448,256,64 +Left Arrow 256,320,26,15 +Right Arrow 256,335,26,15 +Ribbon 256,350,64,16 +*/ +enum TColors +{green=0,blue,yellow,purple,red,white,dblue,orange,grey,circle,COLOR_COUNT}; +hgeSprite *bulletspr[COLOR_COUNT],*towerspr[COLOR_COUNT]; +const double zero=1e-5; +vector2d playerpos; +bool playerLockX,playerLockY; +bool DisableAllTower; +bool DisablePlayer; +bool LOWFPS,diffkey,showdebug; +int VidMode=-1; +hgeTTFont rbPanelFont; +inline double GetDist(vector2d,vector2d); +class Bullet +{ +public: + vector2d bulletpos,bulletdir,limpos; + double dist; + int bullettype,redexplo,redattrib,oriexplo,whicnt; + DWORD sccolor; + /*In Orange bullets + //redattrib also serves as oraattrib to determine if they will explode or change direction + //redexplo also serves as orange explo + //yelbrk serves as direction-change timer + //whicnt describes how much one will explode into (into an exactly circle)*/ + double bulletspeed,bulletaccel,limv; + int exist,inv,addblend; + int whirem,whiskp,yelbrk; + int exp1,exp2; + double lifetime,rot; + bool scollable,collable,extborder; + double scale;int effbrk; + TColors alterColor,alterColor2; + void redir(vector2d targ) + { + bulletdir.x=bulletpos.x-targ.x; + bulletdir.y=bulletpos.y-targ.y; + dist=bulletdir.x*bulletdir.x+bulletdir.y*bulletdir.y; + dist=sqrt(dist); + bulletdir.x/=dist;bulletdir.y/=dist;dist=1; + } + void setdir(double rad) + { + bulletdir.x=cos(rad); + bulletdir.y=sin(rad); + dist=1; + } +}*bullet=NULL; +/*Something about bullets: +//bullettype: +//1: player dir-based green bullet +//2: degree-based blue bullet (for clocks only)[are they clocks?] +//3: 12direction-based blue bullet +//4: yellow chaser bullet +//5: purple slow down bullet +//6: red exploding bullet +//7: white stalled bullet +//8: Orange Redir bullet +//9: dark Blue bullet +//254: Semi-collision effect +//255: Score point*/ +struct Tower +{ + vector2d towerpos; + int towertype; + int towertimer,curtimer; + int towertimer2,curtimer2,shotcount,curshotcount; + bool dblstate; + double bulletspeed; + int redexplo,whicnt,yelbrk; + int exp1,exp2; + int t3t; + bool exist,effect; + double offset; + DWORD RendColor; +}tower[250]; +//t3t is for Tower3 +//0:All 12 directions +//1:four default directions +//2:random left/right +//3:random up/down +struct Target//An annoying circle +{ + hgeSprite *targspr; + vector2d targpos,targdir; + double rot,rotspd; + bool isonshow,isonhide,visible; + void Init(double _rotspd,vector2d ipos) + { + targspr=new hgeSprite(SprSheet,63,71,193,193); + targspr->SetHotSpot(96.5f,96.5f); + rotspd=_rotspd; + rot=0; + targpos=ipos; + } + void TargShow() + { + if (!visible) + isonshow=true,isonhide=false,visible=true; + } + void TargHide() + { + if (visible) + isonhide=true,isonshow=false; + } + void TargShowProc() + { + if (LOWFPS) + targspr->SetColor(SETA(targspr->GetColor(),GETA(targspr->GetColor())+17)); + else + targspr->SetColor(SETA(targspr->GetColor(),GETA(targspr->GetColor())+1)); + if (GETA(targspr->GetColor())>=0x80) + isonshow=isonhide=false,targspr->SetColor(SETA(targspr->GetColor(),0x80)); + } + void TargHideProc() + { + if (LOWFPS) + if(GETA(targspr->GetColor())<17) + targspr->SetColor(SETA(targspr->GetColor(),0)); + else + targspr->SetColor(SETA(targspr->GetColor(),GETA(targspr->GetColor())-17)); + else + targspr->SetColor(SETA(targspr->GetColor(),GETA(targspr->GetColor())-1)); + if (GETA(targspr->GetColor())==0x00) + isonshow=isonhide=visible=false; + } + void TargFollowPlayer() + { + double curspd=0.01f; + if (GetDist(playerpos,targpos)>1)curspd=0.02f;else targpos=playerpos; + if (GetDist(playerpos,targpos)>2)curspd=0.1f; + if (GetDist(playerpos,targpos)>5)curspd=0.5f; + if (GetDist(playerpos,targpos)>10)curspd=0.75f; + if (GetDist(playerpos,targpos)>20)curspd=1.0f; + if (GetDist(playerpos,targpos)>30)curspd=2.0f; + if (GetDist(playerpos,targpos)>40)curspd=5.0f; + targdir.x=targpos.x-playerpos.x; + targdir.y=targpos.y-playerpos.y; + double dist=sqr(targdir.x)+sqr(targdir.y); + dist=sqrt(dist); + if (dist<1e-4)return; + if (LOWFPS) + targpos.x-=targdir.x/dist*curspd*17/20, + targpos.y-=targdir.y/dist*curspd*17/20; + else + targpos.x-=targdir.x/dist*curspd/20, + targpos.y-=targdir.y/dist*curspd/20; + } + void TargGoto(vector2d pos) + { + double curspd=0.01f; + if (GetDist(pos,targpos)>1)curspd=0.25f;else targpos=pos; + if (GetDist(pos,targpos)>2)curspd=0.5f; + if (GetDist(pos,targpos)>5)curspd=1.0f; + if (GetDist(pos,targpos)>10)curspd=2.0f; + if (GetDist(pos,targpos)>20)curspd=3.0f; + if (GetDist(pos,targpos)>30)curspd=4.0f; + if (GetDist(pos,targpos)>40)curspd=5.0f; + targdir.x=targpos.x-pos.x; + targdir.y=targpos.y-pos.y; + double dist=sqr(targdir.x)+sqr(targdir.y); + dist=sqrt(dist); + if (dist<1e-4)return; + if (LOWFPS) + targpos.x-=targdir.x/dist*curspd*17/20, + targpos.y-=targdir.y/dist*curspd*17/20; + else + targpos.x-=targdir.x/dist*curspd/20, + targpos.y-=targdir.y/dist*curspd/20; + } + void TargRender() + { + if (isonshow)TargShowProc();if(isonhide)TargHideProc(); + targspr->RenderEx(targpos.x+7,targpos.y+7,rot,0.8); + if (!DisableAllTower) + { + if (LOWFPS) + rot+=17*rotspd; + else + rot+=rotspd; + } + } +}ATarg,BTarg; +int bulcnt=0,towcnt=0,linecnt=0; +double playerrot; +double playerspeed; +double playerslospeed; +double playerfulspd=0.2; +double playerfulslospd=0.05; +double clockrot,deltarot,deltadelta; +double whirot,dwhirot; +hgeSprite *playerspr; +DWORD DBGColor; +int frameleft,infofade; +int level,part,clrtime,clrbns; +int coll,semicoll,mode,dsmc,restarts; +double clrrange,clrrad,clrmaxrange,clrind,assetime,asts; +hgeSprite *clrcircle; +bool Dis8ref,t8special; +int frameskips=0,stepskips=0; +bool IfCallLevel,IfShowTip,FadeTip,PlayerSplit,charge; +RandomEngine re; +hgeFont *TipFont,*MenuFont; +char lasttip[200]; +int whicnt,whrcnt,shots,clrusg; +bool yelattrib,Complete; +double bsscale; +long long score,scminus; +double mult,lsc; +int multbrk,multbat; +int frms;double averfps; +int plrspd,plrslospd; +int TenSeconds=600,TwentySeconds=1200,ThirtySeconds=1800,AMinute=3600; +int Infinity=1000000000; +int effskp=0; +hgeSprite *Credits,*CreditsRail; +int creditsp;double creditfly,creditacc,credbrk; +bool credstop,creddone; +hgeSprite *Helpspr,*NHelpspr,*HlpL,*HlpR; +double Helpscroll,Hlpyofst;int Helpslide; +bool hshl; +bool tfs; +double scale; +#ifndef WIN32 +double yos; +#endif +int fpslvl,clrmode,sfxvol,bgmvol; +const vector2d splitData[4]={vector2d(0,0),vector2d(400,0),vector2d(0,300),vector2d(400,300)}; +//options from command line arguments +bool fNoSound, +#ifdef WIN32 +noHideConsole, +#endif +fFristStartUp,fFast; +int startLvl,startPrt,fFullScreen; +char alterLog[64]; +#ifdef WIN32 +static const int arFilecount=23; +static const char* archive[]={ +"./Resources/b_diff.png", +"./Resources/b_inter.png", +"./Resources/b_null.png", +"./Resources/e_sflake.png", +"./Resources/e_skyitem.png", +"./Resources/blnsns.png", +"./Resources/charmap.fnt", +"./Resources/vdig.fnt", +"./Resources/bdig.fnt", +"./Resources/ss.png", +"./Resources/help.png", +"./Resources/menus.png", +"./Resources/title.png", +"./Resources/credits.png", +"./Resources/b_leaves.png", +"./Resources/e_leaf.png", +"./Resources/tap.ogg", +"./Resources/menuin.ogg", +"./Resources/menuout.ogg", +"./Resources/Music/BLR2_TR01.ogg", +"./Resources/Music/BLR2_TR07.ogg", +"./Resources/Music/BLR2_TR09.ogg", +"./Resources/Music/CanonTechno.ogg" +}; +#endif +//static const char* GLOBAL_H_FN="global.h"; +static const char* BLRVERSION="1.0.0-0 (r100)"; +static const char *months="JanFebMarAprMayJunJulAugSepOctNovDec"; +char *parseDate(const char *date) +{ + char ms[8]; + int y,d,m;sscanf(date,"%s %d %d",ms,&d,&y); + m=(strstr(months,ms)-months)/3+1; + char *r=new char[16]; + sprintf(r,"%04d-%02d-%02d",y,m,d); + return r; +} +static char* BuiltDate=parseDate(__DATE__); + +void Throw(char *Filename,char *Info) +{ + fprintf(stderr,"%s: %s\n",Filename,Info); + hge->System_Log("%s: %s\n",Filename,Info); +} +void Error(const char *EC,bool hgecreated=false) +{ + hge->System_Log("%s\n",EC); +#ifdef WIN32 + MessageBox(NULL,EC,"Error!",MB_ICONERROR); +#endif + if (hgecreated) + { + hge->System_Shutdown(); + hge->Release(); + } +#ifdef WIN32 + for(int i=0;i<arFilecount;++i)remove(archive[i]); + _rmdir("./Resources/Music"); + _rmdir("./Resources"); +#endif + exit(1); +} +void ShowTip(const char *tip) +{ + if (strcmp(tip,lasttip)!=0) + { + TipFont->SetColor(0x00FFFFFF); + } + memcpy(lasttip,tip,sizeof(lasttip)); + DisableAllTower=true; + DisablePlayer=true; + if (hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT) + FadeTip=true; + double width=TipFont->GetStringWidth(tip); + TipFont->printf(400-width/2,400,HGETEXT_LEFT,tip); + if (FadeTip) + { + if (LOWFPS) + { + if (TipFont->GetColor()>>24>=0x08) + TipFont->SetColor(TipFont->GetColor()-0x8000000); + else + { + DisableAllTower=false; + DisablePlayer=false; + Current_Position=1; + } + } + else + { + if (TipFont->GetColor()>>24>=0x01) + TipFont->SetColor(TipFont->GetColor()-0x1000000); + else + { + DisableAllTower=false; + DisablePlayer=false; + Current_Position=1; + } + } + return; + } + if (!LOWFPS) + { + if (TipFont->GetColor()>>24<=0xFE) + TipFont->SetColor(TipFont->GetColor()+0x01000000); + } + else + { + if (TipFont->GetColor()>>24<=0xF7) + TipFont->SetColor(TipFont->GetColor()+0x08000000); + } +} +void All2pnt();//forward that... + +int AllocBullet() +{ + int i; + if (bulcnt==0) + { + bulcnt=i=1; + bullet=(Bullet*)malloc(sizeof(Bullet)*(bulcnt+1)); + } + else + { + for (i=1;i<=bulcnt;++i) + if (!bullet[i].exist)break; + if (i>bulcnt) + { + bulcnt=i; + Bullet *nblt=(Bullet*)realloc(bullet,sizeof(Bullet)*(bulcnt+1)); + if(!nblt)Error("Error allocating bullets!",1); + bullet=nblt; + } + } + return i; +} +void SigHandler(int pm) +{ + hge->System_Log("Oops, the application ate a piece of DE AD BE EF!"); +#if defined(__GNUC__) && !defined(MINGW_BUILD) + void *strs[64];unsigned cnt; + char **str;cnt=backtrace(strs,64); + str=backtrace_symbols(strs,cnt); + for(unsigned i=0;i<cnt;++i) + hge->System_Log("%s",str[i]); +#endif + hge->System_Shutdown(); + exit(1); +} +void ClearAll(bool cbullet=true) +{ + DisableAllTower=true; + bool none=true; + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist)continue; + if (LOWFPS) + { + if (tower[i].RendColor>>24>=0x08) + { + tower[i].RendColor=tower[i].RendColor-0x8000000; + none=false; + } + } + else + { + if (tower[i].RendColor>>24>=0x01) + { + tower[i].RendColor=tower[i].RendColor-0x1000000; + none=false; + } + } + } + if (none) + { + towcnt=0; + memset(tower,0,sizeof(tower)); + if (cbullet)All2pnt(); + } +} +TextureRect GetTextureRect(int type,TColors color) +{ + if (type==0) + { + switch(color) + { + case green:return TextureRect(48,0,24,24); + case blue:return TextureRect(0,0,24,24); + case yellow:return TextureRect(192,0,24,24); + case purple:return TextureRect(120,0,24,24); + case red:return TextureRect(144,0,24,24); + case white:return TextureRect(168,0,24,24); + case dblue:return TextureRect(24,0,24,24); + case orange:return TextureRect(72,0,24,24); + case grey:return TextureRect(96,0,24,24); + case circle:return TextureRect(24,24,24,24); + default:return TextureRect(0,0,0,0); + } + } + if (type==1) + { + switch(color) + { + case green:return TextureRect(0,136,44,44); + case blue:return TextureRect(0,48,44,44); + case yellow:return TextureRect(180,24,44,44); + case purple:return TextureRect(48,24,44,44); + case red:return TextureRect(92,24,44,44); + case white:return TextureRect(136,24,44,44); + case dblue:return TextureRect(0,92,44,44); + case orange:return TextureRect(0,180,44,44); + default:return TextureRect(0,0,0,0); + } + } + return TextureRect(0,0,0,0); +} +DWORD ColorToDWORD(TColors a) +{ + switch(a) + { + case green:return 0xCCFF00; + case blue:return 0x33CCFF; + case yellow:return 0xFFFF00; + case purple:return 0x9966FF; + case red:return 0xFFFF3333; + case white:return 0xFFFEFEFE; + case dblue:return 0xFF0000FF; + case orange:return 0xFFFF8800; + default:return 0xFF000000; + } +} diff --git a/archive/blr2/src/hgeft.cpp b/archive/blr2/src/hgeft.cpp new file mode 100644 index 0000000..479027b --- /dev/null +++ b/archive/blr2/src/hgeft.cpp @@ -0,0 +1,98 @@ +// Freetype2 ext4hge implementations -*- C++ -*- +#include "hgeft.h" +static const char* HGEFT_SRC_FN="hgeft.cpp"; +void hgeTTChar::Free(){if(quad.tex)hge->Texture_Free(quad.tex),quad.tex=0;} +bool hgeTTChar::SetChar(wchar_t ch,FT_Face ttfface) +{ + FT_GlyphSlot slot=ttfface->glyph; + FT_UInt glyph_index=FT_Get_Char_Index(ttfface,ch); + FT_Error err=FT_Load_Glyph(ttfface,glyph_index,FT_LOAD_DEFAULT); + if(err){hge->System_Log("%s: Glyph load failed!",HGEFT_SRC_FN);return false;} + err=FT_Render_Glyph(ttfface->glyph,FT_RENDER_MODE_NORMAL); + if(err){hge->System_Log("%s: Glyph render failed!",HGEFT_SRC_FN);return false;} + _w=slot->advance.x>>6;_h=slot->bitmap.rows;//we are one line only. + rw=slot->bitmap.width;rh=slot->bitmap.rows; + xofst=slot->bitmap_left; + yofst=slot->bitmap.rows-slot->bitmap_top; + quad.tex=hge->Texture_Create( + slot->bitmap.width?slot->bitmap.width:1, + slot->bitmap.rows?slot->bitmap.rows:1); + DWORD* tx=hge->Texture_Lock(quad.tex,false,0,0, + slot->bitmap.width?slot->bitmap.width:1, + slot->bitmap.rows?slot->bitmap.rows:1); + memset(tx,0,sizeof(DWORD)*(slot->bitmap.width?slot->bitmap.width:1)*(slot->bitmap.rows?slot->bitmap.rows:1)); + int ptr=0; + for(int i=0;i<slot->bitmap.rows;++i) + for(int j=0;j<slot->bitmap.width;++j) + { +#ifdef WIN32 + tx[i*slot->bitmap.width+j]=ARGB(slot->bitmap.buffer[ptr],255,255,255); +#else + tx[(slot->bitmap.rows-i-1)*slot->bitmap.width+j]=ARGB(slot->bitmap.buffer[ptr],255,255,255); + //In OpenGL, textures are locked upside down... +#endif + ptr++; + } + hge->Texture_Unlock(quad.tex); + quad.blend=BLEND_ALPHABLEND; + quad.v[0].tx=0;quad.v[0].ty=0;quad.v[1].tx=1;quad.v[1].ty=0; + quad.v[2].tx=1;quad.v[2].ty=1;quad.v[3].tx=0;quad.v[3].ty=1; + return true; +} +void hgeTTChar::Render(double x,double y,DWORD col) +{ + for(int i=0;i<4;++i)quad.v[i].col=col; + quad.v[0].x=x;quad.v[0].y=y-rh+yofst; + quad.v[1].x=x+rw;quad.v[1].y=y-rh+yofst; + quad.v[2].x=x+rw;quad.v[2].y=y+yofst; + quad.v[3].x=x;quad.v[3].y=y+yofst; + hge->Gfx_RenderQuad(&quad); +} +bool hgeTTFont::Init(const char *ttf,int size) +{ + FT_Error err=FT_Init_FreeType(&libft); + if(err){hge->System_Log("%s: Failed to initialize freetype",HGEFT_SRC_FN);return false;} + err=FT_New_Face(libft,ttf,0,&ttfface); + if(err){hge->System_Log("%s: Failed to load font: %s",HGEFT_SRC_FN,ttf);return false;} + err=FT_Set_Char_Size(ttfface,0,size*64,96,96); + return true; +} +void hgeTTFont::UpdateString(const wchar_t *format, ...) +{ + for(int i=0;buf[i]!='\0';++i)chars[i].Free(); + memset(buf,0,sizeof(buf));memset(chars,0,sizeof(chars)); + va_list vl; + va_start(vl,format); + vswprintf(buf,1024,format,vl); + va_end(vl); + buf[1024]='\0'; + w=h=0; + for(int i=0;buf[i]!='\0';++i) + { + chars[i].SetChar(buf[i],ttfface); + w+=chars[i].w(); + if(chars[i].h()>h)h=chars[i].h(); + } +} +void hgeTTFont::Render(double x,double y,DWORD color,int align) +{ + int cur; + if(align==0) + { + cur=x; + for(int i=0;buf[i]!='\0';++i) + { + chars[i].Render(cur,y,color); + cur+=chars[i].w(); + } + } + if(align==1) + { + cur=x; + for(int i=wcslen(buf)-1;i>=0;--i) + { + chars[i].Render(cur,y,color); + cur-=chars[i].w(); + } + } +} diff --git a/archive/blr2/src/hgeft.h b/archive/blr2/src/hgeft.h new file mode 100644 index 0000000..1badc74 --- /dev/null +++ b/archive/blr2/src/hgeft.h @@ -0,0 +1,75 @@ +// Freetype2 ext4hge header -*- C++ -*- +/* + * Freetype2 extention for hge + * by Chris Xiong + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * + * Note: freetype 2.5.2 or newer is required. + * This library is somehow buggy, known bugs: + * * blinking charcter... + * * segmentation fault(fixed now,not a problem of the library) + * * Slow... but it's hard to improve... + * * Only support a single line... + * + */ +#ifndef HGEEFT_H +#define HGEEFT_H +#include <cstring> +#include <cwchar> +#include "./include/hge.h" +#include <ft2build.h> +#include FT_FREETYPE_H +extern HGE* hge; +class hgeTTChar +{ +private: + hgeQuad quad; + int rw,rh,_w,_h,yofst; +public: + double w(){return _w;} + double h(){return _h;} + void Free(); + bool SetChar(wchar_t ch,FT_Face ttfface); + void Render(double x,double y,DWORD col); +}; +class hgeTTFont +{ +protected: + FT_Library libft; + FT_Face ttfface; + wchar_t buf[1025]; + hgeTTChar chars[1024]; + double w,h; +public: + bool Init(const char *ttf,int size); + double GetWidth(){return w;} + double GetHeight(){return h;} + void UpdateString(const wchar_t *format, ...); + void Render(double x,double y,DWORD color,int align); +}; +#endif diff --git a/archive/blr2/src/levels.h b/archive/blr2/src/levels.h new file mode 100644 index 0000000..58d7505 --- /dev/null +++ b/archive/blr2/src/levels.h @@ -0,0 +1,4305 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Level Implementations +// Copyright Chrisoft 2014 +/* +How to write a classic level/part... +Classic parts need only one procedure, like this. + frameleft=...; + if (towercnt==/!=...)return ClearAll(); + DisableAllTower=false;bulcnt=0;memset(bullet,0,sizeof(bullet)); + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip(""); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + for (int i=1;i<=towcnt;++i) + if (tower[i].towerspr->GetColor()==0x80FFFFFF) + tower[i].towerspr->SetColor(0x00FFFFFF); + for (int i=1;i<=towcnt;++i) + if ((tower[i].towerspr->GetColor()>>24)<=0x80) + tower[i].towerspr->SetColor(tower[i].towerspr->GetColor()+0x01FFFFFF); + else + { + IfCallLevel=false; + return; + } +*/ +/* +How to write an "advanced" part... +"Advanced" parts usually need two or more parts, ont for initalize and one for things to do every frame. +Write on your own thought... +*/ +bool squashrev; +int posx,posy,fskp,posx2,posy2; +bool doneredir; +int pnt1,pnt2; +//Let's start now! +double towers[16];int tcnt; +double dscroll,roll,tbrk; +bool sout,tendone;bool dmt[16]; +//static const char* LEVEL_H_FN="levels.h"; +void Level1Part0(){++part;} +void Level1Part1() +{ + if(DBGColor!=0xFF888820) + { + for(int i=0;i<3;++i) + DBGColor=ColorTransfer(DBGColor,0xFF888820); + return; + } + CreateTower1(400,300,857,2); + frameleft=AMinute*2;clrtime=1; + tcnt=1;sout=false;dscroll=-0.025f;memset(dmt,true,sizeof(dmt)); + for (int i=0;i<tcnt;++i) + { + towers[i]=600+600.0f/(double)tcnt*i+12; + CreateTower3(200,towers[i],428,3,4); + CreateTower3(600,towers[i],428,3,4); + } + ++part;roll=0;tendone=false; + ShowTip("\ +Level 1-Down by the Bank\n\ +Everything going on properly?\n\ +"); + Current_Position=2; +} +void Level1Part2() +{ + for (int i=0;i<tcnt;++i) + { + if (LOWFPS)towers[i]+=17*dscroll;else towers[i]+=dscroll; + tower[2*(i+1)].towerpos.y=tower[2*(i+1)+1].towerpos.y=towers[i]; + if (towers[i]<=300&&towers[i]>=290&&dmt[i]) + { + NewMultpo(tower[2*(i+1)+1].towerpos); + NewMultpo(tower[2*(i+1)].towerpos); + dmt[i]=false; + } + } + if (!sout) + { + if (towers[tcnt-1]<-12)++roll; + for (int i=0;i<tcnt;++i)if (towers[i]<-12)towers[i]=612,dmt[i]=true; + if (roll==1) + for (int i=1;i<=towcnt;++i) + if (tower[i].towertype==3)tower[i].t3t=5; + if (roll==2) + for (int i=1;i<=towcnt;++i) + if (tower[i].towertype==3)tower[i].t3t=0; + if (roll==3&&!tendone) + { + for (int i=1;i<=towcnt;++i) + if (tower[i].towertype==3)tower[i].t3t=4; + tcnt=10; + tendone=true; + for (int i=0;i<tcnt;++i) + { + towers[i]=600+600.0f/(double)tcnt*i+12; + CreateTower3(200,towers[i],428,3,4); + CreateTower3(600,towers[i],428,3,4); + } + } + } +} +void Level1Part3() +{ + frameleft=AMinute;clrtime=1; + if (towcnt!=50&&towcnt!=0)return ClearAll(); + DisableAllTower=false;bulcnt=0;free(bullet);bullet=NULL; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Double-directed Labyrinth!"); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + for (int i=1;i<=25;++i) + CreateTower3(772,i*24-24,1714,2,2), + CreateTower3(28,i*24-12,1714,2,2); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + ++part; + return; + } +} +int labyred; +void Level1Part4() +{ + if (frameleft<=TwentySeconds) + { + if (LOWFPS)labyred+=17;else ++labyred; + if (labyred>=1500)CreateBullet6(re.NextDouble(0,800),re.NextDouble(0,600),2,0,1,12,true),labyred=0; + } + if (frameleft<=TenSeconds&&tower[1].towertimer>857) + for (int i=1;i<=towcnt;++i)tower[i].towertimer=857; +} +BCircle Level2Circle,Level2Circle2; +int fakes[12]; +double L2D; +void Level2Part0() +{ + frameleft=50;L2D=0; + if (towcnt==50) + { + ClearAll(); + return; + } + bulcnt=0;free(bullet);bullet=NULL; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("\ +Level 2-Polygon Mystery\n\ +Place yourself correctly!\ +"); + IfCallLevel=false; + } + if (Current_Position==1) + { + frameleft=0; + return; + } +} +void Level2Part1() +{ + frameleft=AMinute;clrtime=1; + Level2Circle.Init(230,pi/12000,96,vector2d(400,300)); + Level2Circle2.Init(270,-pi/12000,96,vector2d(400,300)); + CreateTower3_fixeddir(400,50,300,3,-2.0f/3.0f*pi); + CreateTower3_fixeddir(400,51,300,3,-1.0f/3.0f*pi); + //======= + CreateTower3_fixeddir(400,550,300,3,2.0f/3.0f*pi); + CreateTower3_fixeddir(400,549,300,3,1.0f/3.0f*pi); + //======= + CreateTower3_fixeddir(616.51,175,300,3,0); + CreateTower3_fixeddir(616.51,176,300,3,-1.0f/3.0f*pi); + //======= + CreateTower3_fixeddir(183.49,175,300,3,-pi); + CreateTower3_fixeddir(183.49,176,300,3,-2.0f/3.0f*pi); + //======= + CreateTower3_fixeddir(616.51,425,300,3,0); + CreateTower3_fixeddir(616.51,424,300,3,1.0f/3.0f*pi); + //======= + CreateTower3_fixeddir(183.49,425,300,3,-pi); + CreateTower3_fixeddir(183.49,424,300,3,2.0f/3.0f*pi); + for (int i=0;i<6;++i)fakes[i]=CreateBullet6(400,300,0,999999999,1,1,false),bullet[fakes[i]].inv=true; + ++part;tbrk=0; +} +void Level2Part2() +{ + Level2Circle.Update(); + Level2Circle2.Update(); + L2D+=hge->Timer_GetDelta(); + double base=Level2Circle.GetRad(); + double r=(Level2Circle.GetRange()+Level2Circle2.GetRange())/2.0f; + for (int i=0;i<6;++i) + bullet[fakes[i]].bulletpos=vector2d(400+r*cos(base+i*pi/3.0f),300+r*sin(base+i*pi/3.0f)); + if (L2D>=1.5) + { + L2D=0;tbrk+=1; + for (int i=0;i<6;++i) + { + CreateBullet6(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f),2,0,1,6,true); + clockrot=0; + if(tbrk>=5)NewMultpo(vector2d(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f))); + } + if(tbrk>=5)tbrk=0; + } +} +void Level2Part3() +{ + frameleft=AMinute;clrtime=1; + for (int i=0;i<6;++i)bullet[fakes[i]].exist=false; + for (int i=0;i<6;++i)fakes[i]=CreateBullet7(400,300,0,999999999,false),bullet[fakes[i]].inv=true; + whicnt=3;clockrot=deltarot=0;++part;tbrk=0; +} +void Level2Part4() +{ + Level2Circle.Update(); + Level2Circle2.Update(); + L2D+=hge->Timer_GetDelta(); + double base=Level2Circle.GetRad(); + double r=(Level2Circle.GetRange()+Level2Circle2.GetRange())/2.0f; + for (int i=0;i<6;++i) + bullet[fakes[i]].bulletpos=vector2d(400+r*cos(base+i*pi/3.0f),300+r*sin(base+i*pi/3.0f)); + if (L2D>=5) + { + L2D=0;tbrk+=1; + for (int i=0;i<6;++i) + { + CreateBullet7(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f),2,0,true); + if(tbrk>=5)NewMultpo(vector2d(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f))); + } + if(tbrk>=5)tbrk=0; + } +} +void Level2Part5() +{ + frameleft=TenSeconds/2; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("You've got 5 seconds to choose a fine place..."); + return; + } + ++part;tbrk=0; +} +Laser Lock; +void Level2Part6() +{ + Level2Circle.Update(); + Level2Circle2.Update(); + L2D+=hge->Timer_GetDelta(); + double base=Level2Circle.GetRad(); + double r=(Level2Circle.GetRange()+Level2Circle2.GetRange())/2.0f; + for (int i=0;i<6;++i) + bullet[fakes[i]].bulletpos=vector2d(400+r*cos(base+i*pi/3.0f),300+r*sin(base+i*pi/3.0f)),bullet[fakes[i]].inv=true; + if (L2D>=5) + { + L2D=0;tbrk+=1; + for (int i=0;i<6;++i) + { + CreateBullet7(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f),2,0,true); + if(tbrk>=5)NewMultpo(vector2d(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f))); + } + if(tbrk>=5)tbrk=0; + } + if (frameleft<TenSeconds/20)++part,frameleft=AMinute,clrtime=1; +} +void Level2Part7() +{ + if (!playerLockY)playerLockY=true; + Level2Circle.Update(); + Level2Circle2.Update(); + L2D+=hge->Timer_GetDelta(); + double base=Level2Circle.GetRad(); + double r=(Level2Circle.GetRange()+Level2Circle2.GetRange())/2.0f; + for (int i=0;i<6;++i) + bullet[fakes[i]].bulletpos=vector2d(400+r*cos(base+i*pi/3.0f),300+r*sin(base+i*pi/3.0f)),bullet[fakes[i]].inv=true; + if (L2D>=5) + { + L2D=0;tbrk+=1; + for (int i=0;i<6;++i) + { + CreateBullet7(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f),2,0,true); + if(tbrk>=5)NewMultpo(vector2d(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f))); + } + if(tbrk>=5)tbrk=0; + } +} +double L2D1; +void Level2Part8() +{ + frameleft=ThirtySeconds;L2D1=0; + playerLockY=false;clrtime=2; + for (int i=6;i<12;++i)fakes[i]=CreateBullet6(400,300,0,999999999,1,1,false),bullet[fakes[i]].inv=true; + ++part;tbrk=0; +} +void Level2Part9() +{ + Level2Circle.Update(); + Level2Circle2.Update(); + L2D+=hge->Timer_GetDelta(); + L2D1+=hge->Timer_GetDelta(); + double base=Level2Circle.GetRad(); + double base2=Level2Circle2.GetRad(); + double r=(Level2Circle.GetRange()+Level2Circle2.GetRange())/2.0f; + for (int i=0;i<6;++i) + bullet[fakes[i]].bulletpos=vector2d(400+r*cos(base+i*pi/3.0f),300+r*sin(base+i*pi/3.0f)); + for (int i=6;i<12;++i) + bullet[fakes[i]].bulletpos=vector2d(400+r*cos(base2+i*pi/3.0f),300+r*sin(base2+i*pi/3.0f)); + if (L2D1>=2) + { + L2D1=0;tbrk+=1; + for (int i=0;i<6;++i) + { + CreateBullet6(403+r*cos(base2+i*pi/3.0f),303+r*sin(base2+i*pi/3.0f),2,0,1,6,true); + clockrot=0; + if(tbrk>=5)NewMultpo(vector2d(403+r*cos(base2+i*pi/3.0f),303+r*sin(base2+i*pi/3.0f))); + } + } + if (L2D>=5) + { + L2D=0;tbrk+=1; + for (int i=0;i<6;++i) + { + CreateBullet7(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f),2,0,true); + if(tbrk>=5)NewMultpo(vector2d(403+r*cos(base+i*pi/3.0f),303+r*sin(base+i*pi/3.0f))); + } + } + if(tbrk>=5)tbrk=0; +} +void Level3Part0() +{ + frameleft=50; + if (towcnt==50) + { + ClearAll(); + return; + } + bulcnt=0;free(bullet);bullet=NULL; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("\ +Level 3-Missing Colour\n\ +A negative omen...\ +"); + IfCallLevel=false; + } + if (Current_Position==1) + { + frameleft=0; + return; + } +} +void Level3Part1() +{ + frameleft=ThirtySeconds;clrtime=0; + if (towcnt!=1&&towcnt!=0)return ClearAll(); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Meet my new weapon...Is it cool?"); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower8(400,300,857,3,57,30,false); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +void Level3Part2() +{ + frameleft=ThirtySeconds;clrtime=0; + if (towcnt!=4&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("What about quad reflective towers...?"); + All2pnt(); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower8(30,10,1250,3,57,15,false); + CreateTower8(746,10,1250,3,57,15,false); + CreateTower8(30,556,1250,3,57,15,false); + CreateTower8(746,556,1250,3,57,15,false); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +TROF fr[6][6]; +int cur; +double elasped; +void Level3Part3() +{ + frameleft=AMinute;clrtime=1; + if (towcnt!=1&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + All2pnt(); + ShowTip("Precise mode is not so precise as expected..."); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower8(400,300,999999999,0,999999999,0,false); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + for (int k=0;k<6;++k) + for (int i=0;i<6;++i) + { + fr[k][i].cnt=10; + fr[k][i].drad=(i+1)*pi/3.0f; + fr[k][i].srad=i*pi/3.0f; + fr[k][i].delay=750; + fr[k][i].stage=-1; + if (k==0)fr[k][i].init(); + } + ++part; + elasped=0;cur=0; + return; + } +} +void Level3Part4() +{ + if (frameleft<TwentySeconds&&tower[1].towertimer==999999999) + { + tower[1].towertimer=tower[1].curtimer=1500; + tower[1].towertimer2=100; + tower[1].bulletspeed=3;tower[1].shotcount=tower[1].curshotcount=10; + } + for (int k=0;k<6;++k) + for (int i=0;i<6;++i) + fr[k][i].update(); + elasped+=hge->Timer_GetDelta(); + if (elasped>3) + { + elasped=0;++cur; + if (cur>=6)cur=0; + double sr=re.NextInt(0,9)*pi/30.0f; + for (int i=0;i<6;++i) + { + fr[cur][i].drad=(i+1)*pi/3.0f+sr; + fr[cur][i].srad=i*pi/3.0f+sr; + fr[cur][i].init(); + } + } +} +double l3p5brk; +void Level3Part5() +{ + frameleft=ThirtySeconds;clrtime=2; + if (towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + All2pnt();BTarg.TargHide(); + ShowTip("Well, here is a..."); + return; + } + ++part;l3p5brk=0; +} +void Level3Part6() +{ + l3p5brk+=hge->Timer_GetDelta(); + if (l3p5brk>0.2) + { + l3p5brk=0; + for (int i=1;i<=8;++i)bullet[CreateBullet8(i*100-50,20,2,false)].setdir(-pi/2); + } +} +void Level4Part0() +{ + frameleft=50;All2pnt();towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("\ +Level 4-Reunion\n\ +What was the weather like yesterday?...\n\ +"); + IfCallLevel=false; + } + if (Current_Position==1) + { + frameleft=0;bulcnt=0;BTarg.TargHide(); + return; + } +} +void Level4Part1() +{ + frameleft=ThirtySeconds;clrtime=0; + if (towcnt!=1&&towcnt!=0)return ClearAll(); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Where is this idea from?"); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower9(400,300,1000,4,750,36,750); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +int redirs[400];int cred; +void Level4Part2() +{ + frameleft=TenSeconds/2;clrtime=0; + if (towcnt==1) + { + ClearAll(); + return; + } + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("..."); + } + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + ATarg.TargShow(); + posx=10,posy=10,doneredir=false; + } +} +void Level4Part3() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>30) + { + fskp=0; + if (posx<766) + { + posx+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part4() +{ + frameleft=TenSeconds/2;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx2=766,posy2=566,doneredir=false; + } +} +void Level4Part5() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>30) + { + fskp=0; + if (posx2>10) + { + posx2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part6() +{ + frameleft=TenSeconds/10*4;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + ATarg.TargShow(); + posx=10,posy=10,doneredir=false; + } +} +void Level4Part7() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>30) + { + fskp=0; + if (posx<766) + { + posx+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part8() +{ + frameleft=TenSeconds/10*4;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx2=766,posy2=566,doneredir=false; + } +} +void Level4Part9() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>30) + { + fskp=0; + if (posx2>10) + { + posx2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part10() +{ + frameleft=TenSeconds/10*3;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + ATarg.TargShow(); + posx=10,posy=10,doneredir=false; + } +} +void Level4Part11() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx<766) + { + posx+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part12() +{ + frameleft=TenSeconds/10*3;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx2=766,posy2=566,doneredir=false; + } +} +void Level4Part13() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx2>10) + { + posx2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part14() +{ + frameleft=TenSeconds/10*2;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + ATarg.TargShow(); + posx=10,posy=10,doneredir=false; + } +} +void Level4Part15() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx<766) + { + posx+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part16() +{ + frameleft=TenSeconds/10*2;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx2=766,posy2=566,doneredir=false; + } +} +void Level4Part17() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx2>10) + { + posx2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level4Part18() +{ + frameleft=TenSeconds;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx=10,posy=10,posx2=766,posy2=566,doneredir=false; + } +} +void Level4Part19() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>33) + { + fskp=0; + if (posx2>10) + { + posx2-=24; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=24; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=2,doneredir=true; + } + if (posx<766) + { + posx+=24; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=24; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + } + } + + } +} +double rot1,dta1,rot2,dta2,spd2,elsp1; +void Level4Part20() +{ + frameleft=AMinute;All2pnt();towcnt=0; + DisableAllTower=false;clrtime=0; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Double Spinner...?"); + } + if (Current_Position==1) + { + BTarg.TargHide();ATarg.TargHide();CreateTower3(400,300,999999999,0,0); + rot1=dta1=rot2=dta2=elsp1=0;spd2=1;++part;IfCallLevel=true; + return; + } +} +void Level4Part21() +{ + elsp1+=hge->Timer_GetDelta(); + if (elsp1<=0.3)return; + elsp1=0; + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + { + dta1+=2*pi/180;dta2-=2*pi/180;spd2=1+4.0f*((AMinute-frameleft)/(double)AMinute); + rot1+=dta1;rot2+=dta2; + } + for (int i=0;i<6;++i)CreateBullet2(400,300,4,rot1+i*pi/3); + for (int i=0;i<6;++i)CreateBullet2(400,300,spd2,rot2+i*pi/3); +} +void Level4Part22() +{ + frameleft=AMinute;clrtime=1; + if (towcnt==1) + { + ClearAll(); + return; + } + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Have problem breathing?\n...so try this!"); + } + if (Current_Position==1) + { + ++part; + pnt1=CreateTower3(10,10,50,20,1); + pnt2=CreateTower3(790,10,50,20,1); + CreateTower9(400,10,2000,2,2000,6,1000); + } +} +void Level4Part23() +{ + if (!LOWFPS) + tower[pnt1].towerpos.x+=0.006,tower[pnt2].towerpos.x-=0.006; + else + tower[pnt1].towerpos.x+=0.006*17,tower[pnt2].towerpos.x-=0.006*17; +} +void Level4Part24() +{ + frameleft=AMinute;clrtime=0; + if (towcnt!=5&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false;All2pnt(); + Current_Position=2; + ShowTip("Let's meet a more classical circle-drawing part...\n\ +...as the end of this level...\nCan you draw perfectly?"); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower4(400,300,2000,2.5); + CreateTower1(9,9,2000,3); + CreateTower1(767,11,2000,3); + CreateTower1(9,567,2000,3); + CreateTower1(767,567,2000,3); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + ++part; + return; + } +} +void Level4Part25() +{ + if(re.NextInt(0,599)==10)NewMultpo(); + for (int i=2;i<=5;++i) + tower[i].towertimer=((frameleft)/(double)AMinute)*1800+200; +} +void Level5Part0() +{ + frameleft=50;All2pnt();towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + LE_Active=true;letex=TLeaf;lescale=0.75; + letr=TextureRect(0,0,108,108);lecolor=0xCCCC3333; + Leaf.Init(); + Current_Position=2; + ShowTip("\ +Level 5-Crazy Autumn\n\ +Autumn is considered as a miserable season for \n\ +thousands of years...\n\ +This autumn, however, is coming too fast...\ +"); + IfCallLevel=false; + } + if (Current_Position==1) + { + frameleft=0; + return; + } +} +void Level5Part1() +{ + frameleft=ThirtySeconds;clrtime=0; + if (towcnt!=2&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower9(400,300,2000,3,1000,36,750); + CreateTower4(400,50,2000,2.5,0); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +void Level5Part2() +{ + frameleft=ThirtySeconds;clrtime=0; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false;All2pnt(); + Current_Position=2; + ShowTip("What if your cheaser is faster than you..."); + return; + } + tower[2].bulletspeed=4;IfCallLevel=false; +} +int pos,lsrbrk; +bool rev; +/**********************\ + * Vortex of Leaves * +\**********************/ +void Level5Part3() +{ + frameleft=AMinute;clrtime=2; + if (towcnt!=0)return (void)ClearAll(); + Lasercnt=12; + for (int i=1;i<=12;++i) + { + laser[i].Init(32); + laser[i].SetTexture(SprSheet,0,264,248,8); + laser[i].RenCtr.x=406,laser[i].RenCtr.y=306; + } + ++part; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false;All2pnt(); + Current_Position=2; + ShowTip("Vortex of leaves..."); + return; + } +} +void Level5Part4() +{ + bool shot=false; + if (LOWFPS)lsrbrk+=16; + if (++lsrbrk>=100)lsrbrk=0,shot=true,++pos; + if (pos==32) + { + pos=0;rev=!rev; + for (int i=1;i<=bulcnt;++i) + if (bullet[i].bullettype==2&&bullet[i].bulletspeed<1e-5) + bullet[i].bulletaccel=0.001, + bullet[i].limv=1+1.5*(frameleft/(double)AMinute); + } + for (int i=1;i<=12;++i) + { + double initrad=pi/6.0f*(i-1); + double dist; + for (int j=0;j<32;++j) + { + dist=j*Resd; + double trad; + if (rev)trad=initrad-j*pi/36.0f;else trad=initrad+j*pi/36.0f; + vector2d t,tt,s; + t.x=cos(trad)*dist; + t.y=sin(trad)*dist; + dist=(j+1)*Resd; + if (rev)trad=initrad-(j+1)*pi/36.0f;else trad=initrad+(j+1)*pi/36.0f; + tt.x=cos(trad)*dist;tt.y=sin(trad)*dist; + tt.x-=t.x;tt.y-=t.y;trad=tt.x;tt.x=tt.y;tt.y=-trad; + trad=sqrt(sqr(tt.x)+sqr(tt.y)); + tt.x/=trad;tt.y/=trad; + //pos: 0~8, mult:0~8 + //pos: 24~32, mult: 8~0 + if (pos>=24) + tt.x*=(32-pos)/1.5f,tt.y*=(32-pos)/1.5f; + else + if (pos<=8) + tt.x*=pos/1.5f,tt.y*=pos/1.5f; + else + tt.x*=5.33f,tt.y*=5.33f; + //We only consider collisions when pos is between 9 and 23. + if (pos>9&&pos<23)laser[i].EnableColl=true;else laser[i].EnableColl=false; + s.x=t.x+tt.x;s.y=t.y+tt.y; + if (j==31) + for (int k=31;k<MaxRes;++k) + laser[i].Setdata(k,t,s,0xEEFF8800); + else + laser[i].Setdata(j,t,s,0xEEFF8800); + trad=initrad+j*pi/36.0f; + if (shot&&j==pos)bullet[CreateBullet2(400+t.x,300+t.y,0.0f,re.NextDouble(0,pi),1)].alterColor=orange; + if (shot&&j==pos&&re.NextInt(0,249)==99)NewMultpo(vector2d(400+t.x,300+t.y)); + } + if (pos>8&&pos<23) + laser[i].EnableColl=true; + else + laser[i].EnableColl=false; + } +} +int tbuls[1000];double lv5brk; +void Level5Part5() +{ + frameleft=AMinute;All2pnt();towcnt=0;Lasercnt=0; + memset(tbuls,0,sizeof(tbuls));lv5brk=0;++part; + clrtime=1; +} +void Level5Part6() +{ + lv5brk+=hge->Timer_GetDelta(); + if (lv5brk<=0.3)return; + lv5brk=0; + for (int i=1;i<=9;++i) + for (int j=0;j<1000;++j) + if (!tbuls[j]) + { + tbuls[j]=CreateBullet2(i*80,570,3,0.5*pi); + break; + } + for (int j=0;j<1000;++j) + if (tbuls[j]&&bullet[tbuls[j]].bulletpos.y<150) + { + if (re.NextInt(1,1000)>=800) + { + if (re.NextInt(1,1000)>=500) + CreateBullet6(bullet[tbuls[j]].bulletpos.x,bullet[tbuls[j]].bulletpos.y,3,200,1,18); + else + if (re.NextInt(1,1000)>=850) + CreateBullet9(bullet[tbuls[j]].bulletpos.x,bullet[tbuls[j]].bulletpos.y,3,500,18,300); + } + BulletEffect_Death(bullet[tbuls[j]],ColorToDWORD(blue)); + bullet[tbuls[j]].exist=false; + tbuls[j]=0; + } +} +void Level5Part7() +{ + frameleft=ThirtySeconds;Dis8ref=true;tbrk=0;clrtime=1; + if (towcnt!=33&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2;All2pnt(); + ShowTip("Threatening effect of high speed bullets"); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + for (int i=1;i<=33;++i)CreateTower8(i*24-12,12,500,10,20,30); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + ++part;tcnt=0; + return; + } +} +void Level5Part8() +{ + tbrk+=hge->Timer_GetDelta(); + if (tbrk<=3)return; + tbrk=0;int tg;++tcnt; + if (re.NextInt(1,1000)>=500)tg=CreateBullet9(200,12,8,300,12,200);else tg=CreateBullet9(600,12,8,300,12,200); + bullet[tg].redir(playerpos); + if (tcnt>4)NewMultpo(),tcnt=0; +} +void Level5Part9() +{ + frameleft=ThirtySeconds;Dis8ref=true;tbrk=0;clrtime=1; + if (towcnt!=66&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2;All2pnt(); + ShowTip("Do not panic!"); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + for (int i=1;i<=33;++i)CreateTower8(i*24-12,12,750,1,1,1),CreateTower8(i*24-12,588,750,1,1,1); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + ++part;tcnt=0; + return; + } +} +void Level5Part10() +{ + tbrk+=hge->Timer_GetDelta(); + if (tbrk<=3)return; + tbrk=0;++tcnt; + if(tcnt>4)NewMultpo(),tcnt=0; + for (int i=0;i<6;++i) + { + int p=CreateBullet2(playerpos.x+cos(i*pi/3.0f)*6,12+sin(i*pi/3.0f)*6,2,-pi/2); + bullet[p].alterColor=orange; + } +} +void Level5Part11() +{ + frameleft=TenSeconds/10*2;clrtime=0;Dis8ref=false; + if (towcnt==66) + { + ClearAll(); + return; + } + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("They are getting out of control...\n\ +Have you noticed that strange things are happening?..."); + } + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1;All2pnt(); + ATarg.TargShow(); + posx=10,posy=10,doneredir=false; + } +} +void Level5Part12() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx<766) + { + posx+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx-400)*0.95+400,(posy-300)*0.95+300,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx-400)*0.95+400,(posy-300)*0.95+300,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level5Part13() +{ + frameleft=TenSeconds/10*2;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx2=766,posy2=566,doneredir=false; + } +} +void Level5Part14() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx2>10) + { + posx2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx2-400)*0.95+400,(posy2-300)*0.95+300,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx2-400)*0.95+400,(posy2-300)*0.95+300,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level5Part15() +{ + frameleft=TenSeconds/10*2;clrtime=0; + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx=10,posy=10,doneredir=false; +} +void Level5Part16() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx<766) + { + posx+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx-400)*0.95+400,(posy-300)*0.95+300,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx-400)*0.9+400,(posy-300)*0.9+300,0,999999,1,999999); + } + else + { + if (posy<566) + { + posy+=12; + redirs[++cred]=CreateBullet9(posx,posy,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx-400)*0.95+400,(posy-300)*0.95+300,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx-400)*0.9+400,(posy-300)*0.9+300,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +void Level5Part17() +{ + frameleft=TenSeconds/2;clrtime=0; + DisableAllTower=false; + if (Current_Position==1) + { + ++part;memset(redirs,0,sizeof(redirs));cred=-1; + posx2=766,posy2=566,doneredir=false; + } +} +void Level5Part18() +{ + if (!LOWFPS)++fskp;else fskp+=17; + if (fskp>15) + { + fskp=0; + if (posx2>10) + { + posx2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx2-400)*0.95+400,(posy2-300)*0.95+300,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx2-400)*0.9+400,(posy2-300)*0.9+300,0,999999,1,999999); + } + else + { + if (posy2>10) + { + posy2-=12; + redirs[++cred]=CreateBullet9(posx2,posy2,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx2-400)*0.95+400,(posy2-300)*0.95+300,0,999999,1,999999); + redirs[++cred]=CreateBullet9((posx2-400)*0.9+400,(posy2-300)*0.9+300,0,999999,1,999999); + } + else + if (!doneredir) + for (int i=0;i<=cred;++i) + bullet[redirs[i]].redir(ATarg.targpos),bullet[redirs[i]].bulletspeed=4,doneredir=true; + } + } +} +double ntrot,ntbrk; +int ntcnt; +void Level5Part19() +{ + frameleft=AMinute;clrtime=1;ntrot=ntbrk=0;ntcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("You are the fish in my barrel."); + } + if (Current_Position==1) + { + ++part;All2pnt(); + ATarg.TargHide();tbrk=0; + } +} +void Level5Part20() +{ + ntbrk+=hge->Timer_GetDelta();tbrk+=hge->Timer_GetDelta(); + if(LOWFPS)ntrot+=16*pi/960.0f;else ntrot+=pi/960.0f; + if(ntbrk<0.01)return; + ntbrk=0;++ntcnt;if (ntcnt>15)ntcnt=0; + int rtatr; + if(frameleft>ThirtySeconds*1.5)rtatr=2; + if(frameleft<=ThirtySeconds*1.5&&frameleft>TenSeconds*4.2)rtatr=0; + if(frameleft<=TenSeconds*4.2&&frameleft>TenSeconds*2.2)rtatr=3; + if(frameleft<=TenSeconds*2.2&&frameleft>TwentySeconds)rtatr=0; + if(frameleft<=TwentySeconds)rtatr=4; + for(int i=0;i<rtatr;++i) + { + int a; + if(ntcnt==0) + a=CreateBullet9(400+250*sin(ntrot+i*2*pi/rtatr),300+250*cos(ntrot+i*2*pi/rtatr),2,500,1,500,true); + else + a=CreateBullet9(400+250*sin(ntrot+i*2*pi/rtatr),300+250*cos(ntrot+i*2*pi/rtatr),2,999999999,1,999999999,true); + bullet[a].redattrib=1;bullet[a].redir(vector2d(400,300)); + bullet[a].bulletdir.x=-bullet[a].bulletdir.x; + bullet[a].bulletdir.y=-bullet[a].bulletdir.y; + if(tbrk>5)NewMultpo(vector2d(400+250*sin(ntrot+i*2*pi/rtatr),300+250*cos(ntrot+i*2*pi/rtatr))); + } + if(tbrk>5)tbrk=0; +} +void Level5Part21() +{ + frameleft=ThirtySeconds; + All2pnt();clrtime=1; + Lasercnt=0; + CTarg.Init(18,75,5.0f); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("This is the UNBREAKABLE jail."); + } + if (Current_Position==1) + { + CreateTower1(30,10,500,2); + CreateTower1(746,10,500,2); + CreateTower1(30,556,500,2); + CreateTower1(746,556,500,2); + ++part; + } +} +void Level5Part22() +{ + int times=1;if (LOWFPS)times=16; + for (int i=1;i<=times;++i) + CTarg.SetRange(CTarg.GetRange()-0.002f); + CTarg.Update(); +} +void Level6Part0() +{ + frameleft=TenSeconds;All2pnt();towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + LE_Active=true;letex=TSflake;lescale=0.2; + letr=TextureRect(0,0,350,350);lecolor=0xCC3366CC; + Leaf.Init(); + Current_Position=2; + ShowTip("\ +Level 6-Peaceful(?) Winter\n\ +Look, there's a question mark in the title...\ +"); + } + if (Current_Position==1) + { + if (!LOWFPS) + DBGColor=ColorTransfer(DBGColor,0xFF60A0FF); + else + for (int i=1;i<=17;++i)DBGColor=ColorTransfer(DBGColor,0xFF60A0FF); + if(DBGColor==0xFF60A0FF)++part; + return; + } +} +void Level6Part1() +{ + //Some component of this level is in towernbullet... + frameleft=ThirtySeconds;clrtime=1; + DisableAllTower=false; + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + whicnt=10; + CreateTower7(400,300,750,3,500); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +int spcnt;double sixrad,sixbrk; +void Level6Part2() +{ + if (towcnt)return ClearAll(false); + All2pnt();frameleft=TenSeconds; + ++part;spcnt=2;sixrad=sixbrk=0; + whicnt=1;DisableAllTower=false; + tbrk=0;clrtime=3; +} +void Level6Part3() +{ + sixbrk+=hge->Timer_GetDelta(); + if (sixrad>2*pi){if(tbrk<1)NewMultpo(vector2d(400,300)),tbrk=100;return;} + if (sixbrk<0.04)return; + sixbrk=0; + sixrad+=pi/25.0f; + for (int i=0;i<spcnt;++i) + { + int pnt=CreateBullet7(400,300,2,1500); + bullet[pnt].setdir(pi/2+sixrad+((double)i/(double)spcnt)*2.0f*pi); + } +} +void Level6Part4() +{ + frameleft=TenSeconds;whrcnt=9; + ++part;spcnt=3;sixrad=sixbrk=0; + whicnt=1;DisableAllTower=false; + tbrk=0; +} +void Level6Part5() +{ + sixbrk+=hge->Timer_GetDelta(); + if (sixrad>2*pi){if(tbrk<1)NewMultpo(vector2d(400,300)),tbrk=100;return;} + if (sixbrk<0.04)return; + sixbrk=0; + sixrad+=pi/25.0f; + for (int i=0;i<spcnt;++i) + { + int pnt=CreateBullet7(400,300,2.2,1500); + bullet[pnt].setdir(pi/2+sixrad+((double)i/(double)spcnt)*2.0f*pi); + } +} +void Level6Part6() +{ + frameleft=TenSeconds;tbrk=0; + ++part;spcnt=4;sixrad=sixbrk=0; + whicnt=1;DisableAllTower=false; +} +void Level6Part7() +{ + sixbrk+=hge->Timer_GetDelta(); + if (sixrad>2*pi){if(tbrk<1)NewMultpo(vector2d(400,300)),tbrk=100;return;} + if (sixbrk<0.04)return; + sixbrk=0; + sixrad+=pi/25.0f; + for (int i=0;i<spcnt;++i) + { + int pnt=CreateBullet7(400,300,2.4,1500); + bullet[pnt].setdir(pi/2+sixrad+((double)i/(double)spcnt)*2.0f*pi); + } +} +void Level6Part8() +{ + frameleft=TenSeconds;whrcnt=6; + ++part;spcnt=5;sixrad=sixbrk=0; + whicnt=1;DisableAllTower=false; + tbrk=0; +} +void Level6Part9() +{ + sixbrk+=hge->Timer_GetDelta(); + if (sixrad>2*pi){if(tbrk<1)NewMultpo(vector2d(400,300)),tbrk=100;return;} + if (sixbrk<0.04)return; + sixbrk=0; + sixrad+=pi/25.0f; + for (int i=0;i<spcnt;++i) + { + int pnt=CreateBullet7(400,300,2.6,1500); + bullet[pnt].setdir(pi/2+sixrad+((double)i/(double)spcnt)*2.0f*pi); + } +} +void Level6Part10() +{ + frameleft=TenSeconds;whrcnt=6; + ++part;spcnt=6;sixrad=sixbrk=0; + whicnt=1;DisableAllTower=false; + tbrk=0; +} +void Level6Part11() +{ + sixbrk+=hge->Timer_GetDelta(); + if (sixrad>2*pi){if(tbrk<1)NewMultpo(vector2d(400,300)),tbrk=100;return;} + if (sixbrk<0.04)return; + sixbrk=0; + sixrad+=pi/25.0f; + for (int i=0;i<spcnt;++i) + { + int pnt=CreateBullet7(400,300,2.6,1500); + bullet[pnt].setdir(pi/2+sixrad+((double)i/(double)spcnt)*2.0f*pi); + } +} +void Level6Part12() +{ + frameleft=AMinute;clrtime=1; + if (towcnt!=8&&towcnt) + { + ClearAll(false); + return; + } + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Get out before you are squashed..."); + } + if (Current_Position==1) + { + ++part;squashrev=false;All2pnt(); + tbrk=0; + CreateTower3(10,10,400,2,1); + CreateTower3(766,10,400,2,1); + CreateTower3(10,566,400,2,1); + CreateTower3(766,566,400,2,1); + CreateTower1(9,9,1000,1.5); + CreateTower1(767,11,1000,1.5); + CreateTower1(9,567,1000,1.5); + CreateTower1(767,567,1000,1.5); + } +} +void Level6Part13() +{ + tbrk+=hge->Timer_GetDelta(); + if(tbrk>=12) + { + for(int i=1;i<=4;++i)NewMultpo(tower[i].towerpos); + tbrk=0; + } + if (!squashrev) + { + if (!LOWFPS) + { + tower[1].towerpos.x+=0.01; + tower[1].towerpos.y+=0.007354; + tower[2].towerpos.x-=0.01; + tower[2].towerpos.y+=0.007354; + tower[3].towerpos.x+=0.01; + tower[3].towerpos.y-=0.007354; + tower[4].towerpos.x-=0.01; + tower[4].towerpos.y-=0.007354; + } + else + { + tower[1].towerpos.x+=0.16; + tower[1].towerpos.y+=0.117664; + tower[2].towerpos.x-=0.16; + tower[2].towerpos.y+=0.117664; + tower[3].towerpos.x+=0.16; + tower[3].towerpos.y-=0.117664; + tower[4].towerpos.x-=0.16; + tower[4].towerpos.y-=0.117664; + } + } + else + { + if (!LOWFPS) + { + tower[1].towerpos.x-=0.01; + tower[1].towerpos.y-=0.007354; + tower[2].towerpos.x+=0.01; + tower[2].towerpos.y-=0.007354; + tower[3].towerpos.x-=0.01; + tower[3].towerpos.y+=0.007354; + tower[4].towerpos.x+=0.01; + tower[4].towerpos.y+=0.007354; + } + else + { + tower[1].towerpos.x-=0.16; + tower[1].towerpos.y-=0.117664; + tower[2].towerpos.x+=0.16; + tower[2].towerpos.y-=0.117664; + tower[3].towerpos.x-=0.16; + tower[3].towerpos.y+=0.117664; + tower[4].towerpos.x+=0.16; + tower[4].towerpos.y+=0.117664; + } + } + if (tower[1].towerpos.x>766||tower[1].towerpos.x<10)squashrev=!squashrev; +} +double avabrk,avacurbrk; +bool dir; +void Level6Part14()//Avalanche +{ + frameleft=AMinute;clrtime=1; + if (towcnt) + { + ClearAll(false); + return; + } + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Avalanche..."); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=1.0f;avacurbrk=tbrk=0;dir=false; + } +} +void Level6Part15() +{ + avacurbrk+=hge->Timer_GetDelta(); + tbrk+=hge->Timer_GetDelta(); + avabrk=((double)frameleft/(double)AMinute)*0.04f+0.01f; + if (avacurbrk>avabrk) + { + avacurbrk=0; + int pnt=CreateBullet2(re.NextDouble(10,790),200,-6.25,3*pi/2.0f); + bullet[pnt].limv=re.NextInt(2,8);bullet[pnt].bulletaccel=0.005; + } + if (tbrk>6)NewMultpo(vector2d(re.NextDouble(20,780),re.NextDouble(20,150))),tbrk=0; +} +void Level6Part16() +{ + frameleft=AMinute;clrtime=2; + if (towcnt) + { + ClearAll(false); + return; + } + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("?.."); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=1.0f; + avacurbrk=0;dir=false;ATarg.TargShow(); + ATarg.targpos=vector2d(400,300); + whicnt=3;avacurbrk=0; + } +} +void Level6Part17() +{ + avacurbrk+=hge->Timer_GetDelta(); + avabrk=((double)frameleft/(double)AMinute)*0.8f+0.2f; + if (avacurbrk>avabrk) + { + avacurbrk=0; + int pnt; + if (re.NextInt(1,100)<=80) + pnt=CreateBullet7(ATarg.targpos.x,ATarg.targpos.y,3,500); + else + pnt=CreateBullet6(ATarg.targpos.x,ATarg.targpos.y,4,1000); + bullet[pnt].dist=1;bullet[pnt].bulletdir=vector2d(0,0); + if(re.NextInt(0,19)==14)NewMultpo(); + } +} +//begin hexagon +Bullet bheader[100],*beewx[1500]; +static int sxcnt,seq,beecnt; +bool brdir; +double offset; +void Level6Part18() +{ + DisableAllTower=false;clrtime=3; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Hexagon loops"); + } + if (Current_Position==1) + { + sxcnt=-1;beecnt=-1;brdir=false;frameleft=TenSeconds;offset=86; + memset(bheader,0,sizeof(bheader)); + memset(beewx,0,sizeof(beewx)); + avacurbrk=1;avabrk=1;sixbrk=0.1;seq=3; + for (int i=1;i<=5;++i) + { + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,10,2,-pi/6); + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,10,2,-5*pi/6); + } + ++part;ATarg.TargHide();All2pnt(); + } +} +void Level6Part19() +{ + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + if (frameleft<TenSeconds/10*1&&!brdir) + { + brdir=true; + for (int i=0;i<=beecnt;++i) + { + beewx[i]->bulletaccel=0.001;beewx[i]->limv=1; + beewx[i]->setdir(re.NextDouble(0,pi)); + } + } + for (int i=0;i<=sxcnt;++i)ProcessBullet2(bheader[i]); + if (avacurbrk>avabrk) + { + avacurbrk=0;++seq;seq%=4; + for (int i=0;i<=sxcnt;++i) + { + if (i&1) + { + switch (seq) + { + case 0:bheader[i].setdir(-5*pi/6);break; + case 1:bheader[i].setdir(-pi/2);break; + case 2:bheader[i].setdir(-pi/6);break; + case 3:bheader[i].setdir(-pi/2);break; + } + } + else + { + switch (seq) + { + case 0:bheader[i].setdir(-pi/6);break; + case 1:bheader[i].setdir(-pi/2);break; + case 2:bheader[i].setdir(-5*pi/6);break; + case 3:bheader[i].setdir(-pi/2);break; + } + } + } + } + if (sixbrk>0.2&&!brdir) + { + sixbrk=0; + if (bheader[0].bulletpos.y>610)return; + for (int i=0;i<=sxcnt;++i) + { + beewx[++beecnt]=&bullet[CreateBullet2(bheader[i].bulletpos.x,bheader[i].bulletpos.y,0,pi,true)]; + } + } +} +void Level6Part20() +{ + sxcnt=-1;beecnt=-1;brdir=false;frameleft=TwentySeconds;offset=43; + memset(bheader,0,sizeof(bheader)); + memset(beewx,0,sizeof(beewx)); + avacurbrk=0.5;avabrk=0.5;sixbrk=0.1;seq=3; + for (int i=1;i<=10;++i) + { + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,10,2,-pi/6); + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,10,2,-5*pi/6); + } + ++part; +} +void Level6Part21() +{ + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + if (frameleft<TenSeconds/10*11&&!brdir) + { + brdir=true; + for (int i=0;i<=beecnt;++i) + { + beewx[i]->bulletaccel=0.001;beewx[i]->limv=1; + beewx[i]->setdir(re.NextDouble(0,pi)); + } + } + for (int i=0;i<=sxcnt;++i)ProcessBullet2(bheader[i]); + if (avacurbrk>avabrk) + { + avacurbrk=0;++seq;seq%=4; + for (int i=0;i<=sxcnt;++i) + { + if (i&1) + { + switch (seq) + { + case 0:bheader[i].setdir(-5*pi/6);break; + case 1:bheader[i].setdir(-pi/2);break; + case 2:bheader[i].setdir(-pi/6);break; + case 3:bheader[i].setdir(-pi/2);break; + } + } + else + { + switch (seq) + { + case 0:bheader[i].setdir(-pi/6);break; + case 1:bheader[i].setdir(-pi/2);break; + case 2:bheader[i].setdir(-5*pi/6);break; + case 3:bheader[i].setdir(-pi/2);break; + } + } + } + } + if (sixbrk>0.2&&!brdir) + { + sixbrk=0; + if (bheader[0].bulletpos.y>610)return; + for (int i=0;i<=sxcnt;++i) + { + beewx[++beecnt]=&bullet[CreateBullet2(bheader[i].bulletpos.x,bheader[i].bulletpos.y,0,pi,true)]; + } + } +} +void Level6Part22() +{ + sxcnt=-1;beecnt=-1;brdir=false;frameleft=TenSeconds/10*7;offset=43; + memset(bheader,0,sizeof(bheader)); + memset(beewx,0,sizeof(beewx)); + avacurbrk=0.25;avabrk=0.25;sixbrk=0.1;seq=3; + for (int i=1;i<=10;++i) + { + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,10,4,-pi/6); + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,10,4,-5*pi/6); + } + ++part; +} +void Level6Part23() +{ + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + if (frameleft<TenSeconds/10*1&&!brdir) + { + brdir=true; + for (int i=0;i<=beecnt;++i) + { + beewx[i]->bulletaccel=0.001;beewx[i]->limv=1; + beewx[i]->setdir(re.NextDouble(0,pi)); + } + } + for (int i=0;i<=sxcnt;++i)ProcessBullet2(bheader[i]); + if (avacurbrk>avabrk) + { + avacurbrk=0;++seq;seq%=4; + for (int i=0;i<=sxcnt;++i) + { + if (i&1) + { + switch (seq) + { + case 0:bheader[i].setdir(-5*pi/6);break; + case 1:bheader[i].setdir(-pi/2);break; + case 2:bheader[i].setdir(-pi/6);break; + case 3:bheader[i].setdir(-pi/2);break; + } + } + else + { + switch (seq) + { + case 0:bheader[i].setdir(-pi/6);break; + case 1:bheader[i].setdir(-pi/2);break; + case 2:bheader[i].setdir(-5*pi/6);break; + case 3:bheader[i].setdir(-pi/2);break; + } + } + } + } + if (sixbrk>0.1&&!brdir) + { + sixbrk=0; + if (bheader[0].bulletpos.y>610)return; + for (int i=0;i<=sxcnt;++i) + { + beewx[++beecnt]=&bullet[CreateBullet2(bheader[i].bulletpos.x,bheader[i].bulletpos.y,0,pi,true)]; + } + } +} +void Level6Part24() +{ + sxcnt=-1;beecnt=-1;brdir=false;frameleft=TenSeconds/10*7;offset=43; + memset(bheader,0,sizeof(bheader)); + memset(beewx,0,sizeof(beewx)); + avacurbrk=0.25;avabrk=0.25;sixbrk=0.1;seq=3; + for (int i=1;i<=10;++i) + { + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,590,4,pi/6); + CreateBullet2(bheader[++sxcnt],offset+2*(i-1)*offset,590,4,5*pi/6); + } + ++part; +} +void Level6Part25() +{ + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + if (frameleft<TenSeconds/10*1&&!brdir) + { + brdir=true; + for (int i=0;i<=beecnt;++i) + { + beewx[i]->bulletaccel=0.001;beewx[i]->limv=1; + beewx[i]->setdir(re.NextDouble(0,pi)); + } + } + for (int i=0;i<=sxcnt;++i)ProcessBullet2(bheader[i]); + if (avacurbrk>avabrk) + { + avacurbrk=0;++seq;seq%=4; + for (int i=0;i<=sxcnt;++i) + { + if (i&1) + { + switch (seq) + { + case 0:bheader[i].setdir(5*pi/6);break; + case 1:bheader[i].setdir(pi/2);break; + case 2:bheader[i].setdir(pi/6);break; + case 3:bheader[i].setdir(pi/2);break; + } + } + else + { + switch (seq) + { + case 0:bheader[i].setdir(pi/6);break; + case 1:bheader[i].setdir(pi/2);break; + case 2:bheader[i].setdir(5*pi/6);break; + case 3:bheader[i].setdir(pi/2);break; + } + } + } + } + if (sixbrk>0.1&&!brdir) + { + sixbrk=0; + if (bheader[0].bulletpos.y<-10)return; + for (int i=0;i<=sxcnt;++i) + { + beewx[++beecnt]=&bullet[CreateBullet2(bheader[i].bulletpos.x,bheader[i].bulletpos.y,0,pi,true)]; + } + } +} +void Level6Part26() +{ + sxcnt=-1;beecnt=-1;brdir=false;frameleft=TenSeconds/10*7;offset=43; + memset(bheader,0,sizeof(bheader)); + memset(beewx,0,sizeof(beewx)); + avacurbrk=0.25;avabrk=0.25;sixbrk=0.1;seq=3; + for (int i=1;i<=10;++i) + { + CreateBullet2(bheader[++sxcnt],790,offset+2*(i-1)*offset,4,5*pi/3); + CreateBullet2(bheader[++sxcnt],790,offset+2*(i-1)*offset,4,pi/3); + } + ++part; +} +void Level6Part27() +{ + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + if (frameleft<TenSeconds/10*1&&!brdir) + { + brdir=true; + for (int i=0;i<=beecnt;++i) + { + beewx[i]->bulletaccel=0.001;beewx[i]->limv=1; + beewx[i]->setdir(re.NextDouble(0,pi)); + } + } + for (int i=0;i<=sxcnt;++i)ProcessBullet2(bheader[i]); + if (avacurbrk>avabrk) + { + avacurbrk=0;++seq;seq%=4; + for (int i=0;i<=sxcnt;++i) + { + if (i&1) + { + switch (seq) + { + case 0:bheader[i].setdir(pi/3);break; + case 1:bheader[i].setdir(0);break; + case 2:bheader[i].setdir(5*pi/3);break; + case 3:bheader[i].setdir(0);break; + } + } + else + { + switch (seq) + { + case 0:bheader[i].setdir(5*pi/3);break; + case 1:bheader[i].setdir(0);break; + case 2:bheader[i].setdir(pi/3);break; + case 3:bheader[i].setdir(0);break; + } + } + } + } + if (sixbrk>0.1&&!brdir) + { + sixbrk=0; + if (bheader[0].bulletpos.x<-10)return; + for (int i=0;i<=sxcnt;++i) + { + beewx[++beecnt]=&bullet[CreateBullet2(bheader[i].bulletpos.x,bheader[i].bulletpos.y,0,pi,true)]; + } + } +} +void Level6Part28() +{ + sxcnt=-1;beecnt=-1;brdir=false;frameleft=TenSeconds+TenSeconds/10*9;offset=43; + memset(bheader,0,sizeof(bheader)); + memset(beewx,0,sizeof(beewx)); + avacurbrk=0.25;avabrk=0.25;sixbrk=0.1;seq=3; + for (int i=1;i<=10;++i) + { + CreateBullet2(bheader[++sxcnt],10,offset+2*(i-1)*offset,4,pi+5*pi/3); + CreateBullet2(bheader[++sxcnt],10,offset+2*(i-1)*offset,4,pi+pi/3); + } + ++part; +} +void Level6Part29() +{ + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + if (frameleft<TenSeconds/10*6&&!brdir) + { + brdir=true; + for (int i=0;i<=beecnt;++i) + { + beewx[i]->bulletaccel=0.001;beewx[i]->limv=1; + beewx[i]->setdir(re.NextDouble(0,pi)); + } + } + for (int i=0;i<=sxcnt;++i)ProcessBullet2(bheader[i]); + if (avacurbrk>avabrk) + { + avacurbrk=0;++seq;seq%=4; + for (int i=0;i<=sxcnt;++i) + { + if (i&1) + { + switch (seq) + { + case 0:bheader[i].setdir(pi+pi/3);break; + case 1:bheader[i].setdir(pi);break; + case 2:bheader[i].setdir(pi+5*pi/3);break; + case 3:bheader[i].setdir(pi);break; + } + } + else + { + switch (seq) + { + case 0:bheader[i].setdir(pi+5*pi/3);break; + case 1:bheader[i].setdir(pi);break; + case 2:bheader[i].setdir(pi+pi/3);break; + case 3:bheader[i].setdir(pi);break; + } + } + } + } + if (sixbrk>0.1&&!brdir) + { + sixbrk=0; + if (bheader[0].bulletpos.x>810)return; + for (int i=0;i<=sxcnt;++i) + { + beewx[++beecnt]=&bullet[CreateBullet2(bheader[i].bulletpos.x,bheader[i].bulletpos.y,0,pi,true)]; + } + } +} +void Level6Part30()//Hyperfluid! +{ + frameleft=AMinute;clrtime=2; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Hyperfluid!"); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=0.2f;avacurbrk=0;sixbrk=-1;tbrk=0; + } +} +void Level6Part999999999()//well this is not an easter egg! +{ + avabrk=(frameleft/(double)AMinute)*0.15f+0.05f; + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + tbrk+=hge->Timer_GetDelta(); + if(tbrk>10)tbrk=0,NewMultpo(vector2d(re.NextDouble(40,100),re.NextDouble(30,75))); + if (avacurbrk>avabrk) + { + avacurbrk=0; + for (int i=1;i<=re.NextInt(1,10);++i) + if (re.NextInt(1,1000)>500) + { + int pnt=CreateBullet2(10,re.NextDouble(10,590),0,-3*pi/4); + bullet[pnt].bulletaccel=0.0025;bullet[pnt].limv=6; + } + else + { + int pnt=CreateBullet2(re.NextDouble(10,790),10,0,-3*pi/4); + bullet[pnt].bulletaccel=0.0025;bullet[pnt].limv=6; + } + } + if (sixbrk>0.5) + { + sixbrk=0; + for (int i=1;i<=re.NextInt(1,10);++i) + { + int pnt=CreateBullet2(re.NextDouble(10,790),590,1,pi/2); + bullet[pnt].alterColor=white; + } + } +} +int bgbrk; +double bgdbbrk; +void Level7Part0() +{ + frameleft=50;All2pnt();towcnt=0;bgbrk=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + LE_Active=false; + Current_Position=2; + ShowTip("\ +Level 7-Rainbow of Spring\n\ +Will there be a clearer day?\ +"); + frameleft=TenSeconds;++part; + } +} +bool skystp; +void Level7Part1() +{ + ++bgbrk;if (LOWFPS)bgbrk+=16; + if (bgbrk<30)return; + bgbrk=0; + if (!LOWFPS) + DBGColor=ColorTransfer(DBGColor,0xFF0B0916); + else + for (int i=1;i<=17;++i)DBGColor=ColorTransfer(DBGColor,0xFF0B0916); + if (DBGColor==0xFF0B0916) + { + frameleft=AMinute,++part;tbrk=0;clrtime=2; + bgdbbrk=re.NextInt(5,20),bgbrk=0; + avabrk=0.2f;avacurbrk=0;skystp=false; + } +} +void Level7Part2() +{ + if (bgbrk==1||bgbrk==4) + { + int times=5;if (LOWFPS)times*=16; + for (int i=1;i<=times;++i)DBGColor=ColorTransfer(DBGColor,0xFF23459A); + if (DBGColor==0xFF23459A) + { + if(bgbrk==1)bgbrk=2; + if(bgbrk==4)bgbrk=5; + } + } + if (bgbrk==2||bgbrk==5) + { + int times=1;if (LOWFPS)times*=16; + for (int i=1;i<=times;++i)DBGColor=ColorTransfer(DBGColor,0xFF0B0916); + if (DBGColor==0xFF0B0916) + { + if(bgbrk==2)bgbrk=3,bgdbbrk=0.06; + if(bgbrk==5)bgbrk=0,bgdbbrk=re.NextInt(5,20); + } + } + if (bgbrk==3||bgbrk==0) + { + bgdbbrk-=hge->Timer_GetDelta(); + if (bgdbbrk<=0) + { + if (bgbrk==0)bgbrk=1; + if (bgbrk==3)bgbrk=4; + } + } + avabrk=(frameleft/(double)AMinute)*0.15f+0.15f; + avacurbrk+=hge->Timer_GetDelta(); + sixbrk+=hge->Timer_GetDelta(); + tbrk+=hge->Timer_GetDelta(); + if (tbrk>10)tbrk=0,NewMultpo(vector2d(re.NextDouble(200,600),re.NextDouble(500,575))); + if (avacurbrk>avabrk) + { + avacurbrk=0; + for (int i=1;i<=re.NextInt(1,10);++i) + { + if (re.NextInt(1,1000)>=500) + { + int pnt=CreateBullet2(10,re.NextDouble(10,590),0,-3*pi/4); + bullet[pnt].bulletaccel=0.0025;bullet[pnt].limv=6; + } + else + { + int pnt=CreateBullet2(re.NextDouble(10,790),10,0,-3*pi/4); + bullet[pnt].bulletaccel=0.0025;bullet[pnt].limv=6; + } + if (re.NextInt(1,1000)>=500) + { + int pnt=CreateBullet2(780,re.NextDouble(10,590),0,-pi/4); + bullet[pnt].bulletaccel=0.0025;bullet[pnt].limv=6; + } + else + { + int pnt=CreateBullet2(re.NextDouble(10,790),10,0,-pi/4); + bullet[pnt].bulletaccel=0.0025;bullet[pnt].limv=6; + } + } + } +} +void Level7Part3() +{ + frameleft=TenSeconds; + if (!skystp) + { + ++bgbrk;if (LOWFPS)bgbrk+=16; + if (bgbrk<30)return; + bgbrk=0; + if (!LOWFPS) + DBGColor=ColorTransfer(DBGColor,0xFFFFFFFF); + else + for (int i=1;i<=17;++i)DBGColor=ColorTransfer(DBGColor,0xFFFFFFFF); + if (DBGColor==0xFFFFFFFF)skystp=skyactive=true,sky.SkySetFadeIn(),sky.SetSpeed(0.01); + sky.SetTime(9); + } + else + { + ++bgbrk;if (LOWFPS)bgbrk+=16; + if (bgbrk<30)return; + bgbrk=0; + if (!LOWFPS) + DBGColor=ColorTransfer(DBGColor,0x00FFFFFF); + else + for (int i=1;i<=17;++i)DBGColor=ColorTransfer(DBGColor,0x00FFFFFF); + if (DBGColor==0x00FFFFFF) + ++part; + } +} +void Level7Part4() +{ + frameleft=(AMinute+ThirtySeconds);clrtime=3; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Rainbow tower..."); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + towcnt=0; + deltadelta=pi/720; + CreateTower6(400,300,600,2,1000,3,72); + ++part;All2pnt(); +} +void Level7Part5() +{ + ++frameskips; + if (tower[1].towertype==6) + { + if (frameskips>TenSeconds/5) + { + frameskips=0; + towcnt=0; + CreateTower9(400,300,600,2,1500,72,1200); + } + } + if (tower[1].towertype==9) + { + if (frameskips>TenSeconds/5) + { + frameskips=0; + towcnt=0; + CreateTower4(400,300,500,1,500); + } + } + if (tower[1].towertype==4) + { + if (frameskips>TenSeconds/5) + { + frameskips=0; + towcnt=0; + CreateTower1(400,300,50,4); + } + } + if (tower[1].towertype==1) + { + if (frameskips>TenSeconds/5) + { + frameskips=0; + towcnt=0; + CreateTower2(400,300,50,4); + } + } + if (tower[1].towertype==2) + { + if (frameskips>TenSeconds/2) + { + frameskips=0; + towcnt=0; + CreateTower8(400,300,500,5,20,50); + } + } + if (tower[1].towertype==8) + { + BTarg.TargHide(); + if (frameskips>TenSeconds/5) + { + frameskips=0; + towcnt=0; + CreateTower5(400,300,50,5); + } + } + if (tower[1].towertype==5) + { + if (frameskips>TenSeconds/5) + { + frameskips=0; + towcnt=0; + CreateTower6(400,300,600,2,1000,3,72); + } + } +} +void Level7Part6() +{ + frameleft=AMinute;clrtime=2;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Hit Z..."); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=1.0f;avacurbrk=0; + } +} +void Level7Part7() +{ + avabrk=frameleft/(double)AMinute*0.5f+0.5f; + avacurbrk+=hge->Timer_GetDelta(); + if (avacurbrk>avabrk) + { + if(re.NextInt(0,4)==0)NewMultpo(); + avacurbrk=0; + bool lasta,lastb; + lasta=re.NextInt(1,1000)<500;lastb=re.NextInt(1,1000)<500; + for (int i=0;i<31;++i) + { + int rf=re.NextInt(0,999); + if ((lasta&&rf<600)||(!lasta&&rf<250)) + { + int pnt=CreateBullet2(-15,i*20,2,pi); + bullet[pnt].alterColor=(TColors)(i%8); + bullet[pnt].limv=2+2*(AMinute-frameleft)/(double)AMinute;bullet[pnt].bulletaccel=0.002; + lasta=true; + }else lasta=false; + rf=re.NextInt(0,999); + if ((lastb&&rf<600)||(!lastb&&rf<250)) + { + int pnt=CreateBullet2(815,i*20-10,2,0); + bullet[pnt].alterColor=(TColors)(i%8); + bullet[pnt].limv=2+2*(AMinute-frameleft)/(double)AMinute;bullet[pnt].bulletaccel=0.002; + lastb=true; + }else lastb=false; + } + } +} +double sntang; +void Level7Part8() +{ + frameleft=AMinute;clrtime=2;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Rainbow!"); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=0.03f;avacurbrk=1.0f;sntang=-pi/2; + } +} +void rainbowCreator(double rl,double rr,double rad,TColors col,double speed,bool invi=false) +{ + double r=re.NextDouble(rr,rl); + int pnt=CreateBullet2(900+cos(rad)*r,700+sin(rad)*r,speed,re.NextDouble(0,pi),true,invi); + bullet[pnt].alterColor=col; +} +void Level7Part9() +{ + if (sntang>-pi) + { + avacurbrk+=hge->Timer_GetDelta(); + if (avacurbrk>avabrk) + { + sntang-=pi/180;avacurbrk=0; + for(int i=0;i<6;++i)rainbowCreator(660,600,sntang,red,0,1); + for(int i=0;i<6;++i)rainbowCreator(610,550,sntang,orange,0,1); + for(int i=0;i<6;++i)rainbowCreator(560,500,sntang,yellow,0,1); + for(int i=0;i<6;++i)rainbowCreator(510,450,sntang,green,0,1); + for(int i=0;i<6;++i)rainbowCreator(460,410,sntang,blue,0,1); + for(int i=0;i<6;++i)rainbowCreator(420,360,sntang,dblue,0,1); + for(int i=0;i<6;++i)rainbowCreator(365,310,sntang,purple,0,1); + } + } + else + { + avabrk=0.25+(frameleft/(double)AMinute)*0.5f; + avacurbrk+=hge->Timer_GetDelta(); + if (avacurbrk>avabrk) + { + avacurbrk=0; + if(re.NextInt(0,19)==7)NewMultpo(); + double spd=((AMinute-frameleft)/(double)AMinute)+1; + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(660,600,sntang,red,spd); + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(610,550,sntang,orange,spd); + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(560,500,sntang,yellow,spd); + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(510,450,sntang,green,spd); + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(460,410,sntang,blue,spd); + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(420,360,sntang,dblue,spd); + for(int i=0;i<((AMinute-frameleft)/(double)AMinute)*20;++i) + sntang=re.NextDouble(-pi,-pi/2), + rainbowCreator(365,310,sntang,purple,spd); + sntang=-pi-0.1; + } + } +} +SimpleThing aa,bb; +void Level7Part10() +{ + frameleft=AMinute*2;clrtime=1;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Interference(fake)"); + } + if (Current_Position==1) + { + ++part;All2pnt();skyactive=false;DBGColor=0xFF000000; + binter.Init("./Resources/b_inter.png",PicBack::Centered,0x80); + binter.SetFadeIn();aa.Init(vector2d(260,292));bb.Init(vector2d(523,292)); + } +} +void Level7Part11() +{ +//260,292;523,292 + aa.Update(true);bb.Update(false); +} +diffCreator dfc[200]; +void Level7Part12() +{ + frameleft=AMinute*2;clrtime=3;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false;bulcnt=0; + aa.toPoint();bb.toPoint(); + Current_Position=2; + ShowTip("Diffraction(fake)"); + } + if (Current_Position==1) + { + ++part;memset(dfc,0,sizeof(dfc)); + binter.SetFadeOut();bdiff.Init("./resources/b_diff.png",PicBack::Tiled,0x80); + bdiff.SetFadeIn();bdiff.SetScale(0.5); + avabrk=2.0f;avacurbrk=0; + } +} +void Level7Part13() +{ + avabrk=1.0f+frameleft/(double)AMinute; + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk&&frameleft>=TenSeconds/5) + { + for(int i=0;i<200;++i) + if (!dfc[i].isActive()) + { + if(re.NextInt(1,100)>=75) + { + if(re.NextInt(1,100)>=50) + { + vector2d pos=vector2d(playerpos.x,re.NextDouble(0,600)); + while (GetDist(pos,playerpos)<100) + pos=vector2d(playerpos.x,re.NextDouble(0,600)); + dfc[i].init(pos); + } + else + { + vector2d pos=vector2d(re.NextDouble(0,800),playerpos.y); + while (GetDist(pos,playerpos)<100) + pos=vector2d(re.NextDouble(0,800),playerpos.y); + dfc[i].init(pos); + } + } + else + { + vector2d pos=vector2d(re.NextDouble(0,800),re.NextDouble(0,600)); + while (GetDist(pos,playerpos)<100) + pos=vector2d(re.NextDouble(0,800),re.NextDouble(0,600)); + dfc[i].init(pos); + if(re.NextInt(0,7)==3)NewMultpo(pos); + } + break; + } + avacurbrk=0; + } + for(int i=0;i<200;++i) + if(dfc[i].isActive())dfc[i].update(); +} +BulletSine bnl[100]; +double ykbrk; +void Level7Part14()//Photon school +{ + memset(bnl,0,sizeof(bnl)); + frameleft=AMinute;clrtime=2; + ykbrk=0.5f;skyactive=true;bdiff.SetFadeOut(); + if((DBGColor=ColorTransfer(DBGColor,0x00000000))==0x0)++part; +} +void Level7Part15() +{ + ykbrk-=hge->Timer_GetDelta(); + if (ykbrk<0&&frameleft>TenSeconds/10*3) + { + ykbrk=(double)frameleft/AMinute*0.75f+0.75f; + for (int i=0;i<100;++i) + if (!bnl[i].active) + { + vector2d a,b; + if (re.NextInt(1,100)>=50) + { + if (re.NextInt(1,100)>=50)a=vector2d(re.NextDouble(10,790),610);else a=vector2d(re.NextDouble(10,790),-10); + } + else + { + if (re.NextInt(1,100)>=50)a=vector2d(-10,re.NextDouble(10,590));else a=vector2d(810,re.NextDouble(10,590)); + } + if (re.NextInt(1,100)>=50) + { + if (re.NextInt(1,100)>=50)b=vector2d(re.NextDouble(10,790),610);else b=vector2d(re.NextDouble(10,790),-10); + } + else + { + if (re.NextInt(1,100)>=50)b=vector2d(-10,re.NextDouble(10,590));else b=vector2d(810,re.NextDouble(10,590)); + } + bnl[i].Init(a,b); + break; + } + } + for (int i=0;i<100;++i) + if (bnl[i].active)bnl[i].Update(); +} +double DTCircle; +BCircle Circles[20]; +int CCnt,state; +void Level7Part16()//Great circles +{ + towcnt=0;clrtime=0; + frameleft=Infinity;All2pnt(); + Circles[0].Init(444,20*pi/50000.0f,6,vector2d(400,300)); + Circles[1].Init(444,-20*pi/50000.0f,6,vector2d(400,300)); + CCnt=1;state=0; + DTCircle=0.0f; + ++part;playerpos.x=400,playerpos.y=300; +} +void Level7Part17()//Great circles-child1 +{ + frameleft=Infinity; + DTCircle+=hge->Timer_GetDelta(); + if (DTCircle>1&&CCnt<3) + { + Circles[2].Init(444,10*pi/50000.0f,12,vector2d(400,300)); + Circles[3].Init(444,-10*pi/50000.0f,12,vector2d(400,300)); + CCnt=3; + } + if (DTCircle>2&&CCnt<5) + { + Circles[4].Init(444,8*pi/50000.0f,18,vector2d(400,300)); + Circles[5].Init(444,-8*pi/50000.0f,18,vector2d(400,300)); + CCnt=5; + } + if (DTCircle>3&&CCnt<7) + { + Circles[6].Init(444,8*pi/50000.0f,27,vector2d(400,300)); + Circles[7].Init(444,-8*pi/50000.0f,27,vector2d(400,300)); + CCnt=7; + } + if (DTCircle>4&&CCnt<9) + { + Circles[8].Init(444,6*pi/50000.0f,45,vector2d(400,300)); + Circles[9].Init(444,-6*pi/50000.0f,45,vector2d(400,300)); + CCnt=9; + } + if (DTCircle>5&&CCnt<11) + { + Circles[10].Init(444,6*pi/50000.0f,60,vector2d(400,300)); + Circles[11].Init(444,-6*pi/50000.0f,60,vector2d(400,300)); + CCnt=11; + } + if (DTCircle>5&&CCnt<13) + { + Circles[12].Init(444,3*pi/50000.0f,96,vector2d(400,300)); + Circles[13].Init(444,-3*pi/50000.0f,96,vector2d(400,300)); + CCnt=13; + } + if (Circles[0].GetRange()>=50) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[0].SetRange(Circles[0].GetRange()-0.1), + Circles[1].SetRange(Circles[1].GetRange()-0.1); + } + if (Circles[2].GetRange()>=100&&CCnt>=3) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[2].SetRange(Circles[2].GetRange()-0.1), + Circles[3].SetRange(Circles[3].GetRange()-0.1); + } + if (Circles[4].GetRange()>=150&&CCnt>=5) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[4].SetRange(Circles[4].GetRange()-0.1), + Circles[5].SetRange(Circles[5].GetRange()-0.1); + } + if (Circles[6].GetRange()>=210&&CCnt>=7) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[6].SetRange(Circles[6].GetRange()-0.1), + Circles[7].SetRange(Circles[7].GetRange()-0.1); + } + if (Circles[8].GetRange()>=270&&CCnt>=9) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[8].SetRange(Circles[8].GetRange()-0.1), + Circles[9].SetRange(Circles[9].GetRange()-0.1); + } + if (Circles[10].GetRange()>=320&&CCnt>=11) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[10].SetRange(Circles[10].GetRange()-0.1), + Circles[11].SetRange(Circles[11].GetRange()-0.1); + } + if (Circles[12].GetRange()>=420&&CCnt>=13) + { + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + Circles[12].SetRange(Circles[12].GetRange()-0.1), + Circles[13].SetRange(Circles[13].GetRange()-0.1); + } + else + { + if (CCnt>=13)++part; + for (int i=1;i<=CCnt;++i) + Circles[i].SetDT(i*pi); + } + for (int i=0;i<=CCnt;++i)Circles[i].Update(); + state=0; + towerspr[red]->RenderStretch(770,0,800,30); + towerspr[green]->RenderStretch(380,280,420,320); +} +void Level7Part18()//Great circles-child2 +{ + if(state) + { + towerspr[green]->RenderStretch(770,0,800,30); + towerspr[red]->RenderStretch(380,280,420,320); + } + else + { + towerspr[red]->RenderStretch(770,0,800,30); + towerspr[green]->RenderStretch(380,280,420,320); + } + hgeRect col; + if (state) + { + col=hgeRect(380,280,420,320); + if (col.TestPoint(playerpos.x,playerpos.y))++part; + } + else + { + col=hgeRect(770,0,800,30); + if (col.TestPoint(playerpos.x,playerpos.y))state=1; + } + frameleft=Infinity; + for (int i=0;i<=CCnt;++i) + { + if (i==0||i==1)Circles[i].SetRange(50+10*sin(Circles[i].GetDT())); + if (i==2||i==3)Circles[i].SetRange(100+10*sin(Circles[i].GetDT())); + if (i==4||i==5)Circles[i].SetRange(150+10*sin(Circles[i].GetDT())); + if (i==6||i==7)Circles[i].SetRange(210+20*sin(Circles[i].GetDT())); + if (i==8||i==9)Circles[i].SetRange(270+20*sin(Circles[i].GetDT())); + if (i==10||i==11)Circles[i].SetRange(320+20*sin(Circles[i].GetDT())); + if (i==12||i==13)Circles[i].SetRange(420+30*sin(Circles[i].GetDT())); + Circles[i].Update(); + } +} +BTail btails[50]; +void Level7Part19() +{ + frameleft=AMinute*2;clrtime=3;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Warning: Trypophobia caution ahead!"); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=1.0f;avacurbrk=1.0f;memset(btails,0,sizeof(btails)); + } +} +void Level7Part20() +{ + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk) + { + avacurbrk=0;avabrk=(frameleft/(double)(AMinute*2))*0.7+0.3; + for(int i=0;i<50;++i) + if(!btails[i].isActive()) + {btails[i].Create();break;} + if(re.NextInt(0,24)==15)NewMultpo(); + } + for(int i=0;i<50;++i) + if(btails[i].isActive())btails[i].Update(); +} +int sttnt; +void Level7Part21() +{ + frameleft=AMinute+ThirtySeconds;All2pnt();clrtime=1; + if (towcnt!=1&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + t8special=true; + sttnt=CreateTower8(400,300,2000,2,75,20); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + ++part; + return; + } +} +void Level7Part22() +{ + tower[sttnt].towertimer=(frameleft/(double)(AMinute+ThirtySeconds))*1250+750; +} +WOP wop[100]; +void Level7Part23()//Wave of Photon +{ + memset(bnl,0,sizeof(bnl));t8special=false; + frameleft=AMinute;All2pnt();towcnt=0; + ykbrk=0.5f;++part;clrtime=1; +} +void Level7Part24() +{ + ykbrk-=hge->Timer_GetDelta(); + if (ykbrk<0&&frameleft>TenSeconds/10*3) + { + ykbrk=(double)frameleft/AMinute/2.0f+0.2f; + for (int i=0;i<100;++i) + if (!wop[i].active) + { + vector2d a,b; + if (re.NextInt(1,100)>=50) + { + if (re.NextInt(1,100)>=50)a=vector2d(re.NextDouble(10,790),610);else a=vector2d(re.NextDouble(10,790),-10); + } + else + { + if (re.NextInt(1,100)>=50)a=vector2d(-10,re.NextDouble(10,590));else a=vector2d(810,re.NextDouble(10,590)); + } + if (re.NextInt(1,100)>=50) + { + if (re.NextInt(1,100)>=50)b=vector2d(re.NextDouble(10,790),610);else b=vector2d(re.NextDouble(10,790),-10); + } + else + { + if (re.NextInt(1,100)>=50)b=vector2d(-10,re.NextDouble(10,590));else b=vector2d(810,re.NextDouble(10,590)); + } + if (re.NextInt(1,100)>=80) + { + vector2d d=playerpos-a; + b=playerpos; + while(b.x>-5&&b.x<805&&b.y>-5&&b.y<605)b=b+d; + } + wop[i].Init(a,b,1+(AMinute-frameleft)/(double)AMinute,0.02); + break; + } + } + for (int i=0;i<100;++i) + if (wop[i].active)wop[i].Update(); +} +RTV rtv[100]; +void Level7Part25() +{ + frameleft=AMinute+ThirtySeconds; + All2pnt();towcnt=Lasercnt=0; + ++part;memset(rtv,0,sizeof(rtv)); + avabrk=1;avacurbrk=0.7;clrtime=1; +} +void Level7Part26() +{ + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk&&frameleft>TenSeconds/3) + { + avacurbrk=0;avabrk=frameleft/(double)(AMinute+ThirtySeconds)*1.25+0.75; + for(int i=0;i<100;++i)if(!rtv[i].isActive()) + { + int spinner=6; + if(frameleft<AMinute)spinner=8; + if(frameleft<ThirtySeconds)spinner=12; + if(re.NextInt(1,100)>=40)rtv[i].Init(1,(re.NextInt(0,1)?1:-1)*pi/123,spinner,(TColors)(re.NextInt(0,7)),re.NextInt(0,11)); + else if(re.NextInt(0,1)) + rtv[i].Init(2,(re.NextInt(0,1)?1:-1)*pi/60,spinner,(TColors)(re.NextInt(0,7)),re.NextInt(0,11)); + else + rtv[i].Init(3,pi/48,spinner,(TColors)(re.NextInt(0,7)),re.NextInt(0,11)); + break; + } + } + for(int i=0;i<100;++i)if(rtv[i].isActive())rtv[i].Update(); +} +//Level-1 stats from here +void Levelm1Part0() +{ + frameleft=50;All2pnt();towcnt=0;bgbrk=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + LE_Active=false; + Current_Position=2; + ShowTip("\ +Level -1-Over the Horizon\n\ +Level -1! Getting ready?\ +"); + frameleft=TenSeconds;++part; + } +} +void Levelm1Part1()//3 circles +{ + frameleft=AMinute;clrtime=2;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("RGB..."); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=1.0f;avacurbrk=0;tbrk=0; + } +} +void CircCreator(vector2d p,int cnt,TColors col) +{ + for (int i=0;i<cnt;++i) + { + int pnt=CreateBullet2(p.x,p.y,6,frameleft*pi/AMinute+i*(2*pi/cnt)); + // ^ + // Nowhere can be safe! + bullet[pnt].alterColor=col; + bullet[pnt].bulletaccel=-0.003;bullet[pnt].limv=((AMinute-frameleft)/(double)AMinute)+1.0f; + } +} +void Levelm1Part2() +{ + avacurbrk+=hge->Timer_GetDelta(); + tbrk+=hge->Timer_GetDelta(); + avabrk=(frameleft/(double)AMinute)*0.5f+0.5f; + if(tbrk>8)tbrk=0,NewMultpo(vector2d(400,300)); + if(avacurbrk>avabrk) + { + avacurbrk=0; + CircCreator(vector2d(400,250),60,red); + CircCreator(vector2d(350,336.6),60,green); + CircCreator(vector2d(450,336.6),60,blue); + } +} +BCircle scircles[200]; +double rspd[200]; +void Levelm1Part3()//circles +{ + frameleft=AMinute;clrtime=1;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("??????"); + } + if (Current_Position==1) + { + ++part;All2pnt();avabrk=1.0f;avacurbrk=1.0f;memset(scircles,0,sizeof(scircles)); + } +} +void Levelm1Part4() +{ + avacurbrk+=hge->Timer_GetDelta(); + avabrk=0.1+(frameleft/(double)AMinute)*0.4f; + if(avacurbrk>avabrk) + { + avacurbrk=0; + for(int i=0;i<200;++i) + { + if (scircles[i].GetRange()>510||scircles[i].GetRange()<1e-7) + { + scircles[i].Init(1,(re.NextInt(0,1)?1:-1)*(frameleft<TwentySeconds?0.0003:0.0002),36,vector2d(400,300),(TColors)re.NextInt(0,7),(TColors)re.NextInt(0,7)); + rspd[i]=0.575+(frameleft/(double)AMinute)*0.1;break; + } + } + } + for(int i=0;i<200;++i) + { + if (scircles[i].GetRange()>1e-7&&scircles[i].GetRange()<510) + { + scircles[i].SetRange(scircles[i].GetRange()+(LOWFPS?17:1)*rspd[i]); + if (rspd[i]>0.002)rspd[i]-=0.0005*(LOWFPS?17:1); + if (rspd[i]<=0.002)rspd[i]=0.002; + scircles[i].Update(); + } + } +} +void Levelm1Part5()//Spiky +{ + frameleft=AMinute+ThirtySeconds; + for(int i=0;i<200;++i) + if (scircles[i].GetRange()>1e-7&&scircles[i].GetRange()<510) + scircles[i].circ2pnt(); + towcnt=0;clrtime=1; + Lasercnt=0; + ++part;avabrk=1;avacurbrk=0.5; +} +void Levelm1Part6()//Spiky-child +{ + avacurbrk+=hge->Timer_GetDelta(); + if (avacurbrk>avabrk) + { + avacurbrk=0;avabrk=frameleft/(double)(AMinute+ThirtySeconds)*0.4+0.1; + for (int i=0;i<1000;++i) + { + if (!noname[i].Exist()) + { + if (frameleft<TenSeconds) + noname[i].Init(re.NextDouble(0,800),4,100,150,60,0x8033CCFF); + else if (frameleft<TwentySeconds) + noname[i].Init(re.NextDouble(0,800),4,100,150,65,0x8033CCFF); + else noname[i].Init(re.NextDouble(0,800),4,100,150,75,0x8033CCFF); + break; + } + } + if(re.NextInt(0,19)==8)NewMultpo(); + } + for (int i=0;i<1000;++i)if (noname[i].Exist())noname[i].Process(); +} +achromaGroup aca,acb; +void Levelm1Part7()//Achromatopsia1 +{ + frameleft=AMinute;for(int i=0;i<1000;++i)if(noname[i].Exist())noname[i].noname2pnt(); + aca.Init(red,0.075);acb.Init(green,0.075);clrtime=1; + ++part;avabrk=2.0f;avacurbrk=0;achromab=false; +} +void Levelm1Part8()//Achromatopsia1-child +{ + avacurbrk+=hge->Timer_GetDelta(); + if (avacurbrk>avabrk) + { + avacurbrk=0;avabrk=2; + aca.Reverse();acb.Reverse(); + if(re.NextInt(0,7)==3)NewMultpo(vector2d(re.NextInt(10,790),re.NextInt(500,590))); + } + aca.Update(1);acb.Update(); +} +void Levelm1Part9()//Achromatopsia2 +{ + frameleft=AMinute;clrtime=1; + aca.Init(red,1);acb.Init(green,1); + ++part;avabrk=1.5f;avacurbrk=0;achromab=true; +} +void Levelm1Part10()//Achromatopsia2-child +{ + avacurbrk+=hge->Timer_GetDelta(); + if (avacurbrk>avabrk) + { + avacurbrk=0;avabrk=2; + aca.Reverse();acb.Reverse(); + } + aca.Update();acb.Update(); +} +void Levelm1Part11() +{ + frameleft=AMinute+ThirtySeconds;clrtime=2; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("I've heard that all of you\n\ +support hyper-threading?"); + return; + } + ++frameskips; + if(!PlayerSplit)playerpos=vector2d(200,150),PlayerSplit=true; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower8(400,300,857,3,57,20,false); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + { + aca.achroma2pnt();acb.achroma2pnt(); + tower[i].RendColor=0x00FFFFFF; + } + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +void Levelm1Part12() +{ + frameleft=ThirtySeconds;if(tower[towcnt].towertype!=6)towcnt=0; + DisableAllTower=false; + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower6(400,300,2500,2,2000,3,12); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false;BTarg.TargHide(); + return; + } +} +int m19lead[10],m19gen[700]; +double m19rad; +int m19step,m19cnt; +bool m19pldir; +void Levelm1Part13()//Gravity Vortex +{ + frameleft=AMinute*2;towcnt=0;PlayerSplit=false; + clrtime=2; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Who's collecting such great power here?"); + return; + } + if (!LOWFPS) + DBGColor=ColorTransfer(DBGColor,0xFF000000); + else + for (int i=1;i<=17;++i)DBGColor=ColorTransfer(DBGColor,0xFF000000); + if (DBGColor==0xFF000000) + { + All2pnt();memset(m19lead,0,sizeof(m19lead)); + memset(m19gen,0,sizeof(m19gen)); + ++part;m19rad=m19step=m19cnt=0; + avabrk=0.05;avacurbrk=0; + for(int i=0;i<8;++i) + { + m19lead[i]=CreateBullet2(400,300,0,0); + bullet[m19lead[i]].bulletpos=vector2d(400+250*cos(m19rad+i*pi/4),300+250*sin(m19rad+i*pi/4)); + bullet[m19lead[i]].alterColor=(TColors)i; + bullet[m19lead[i]].inv=true; + } + m19pldir=false;BTarg.targpos=playerpos; + } +} +void Levelm1Part20update() +{ + if(!m19pldir)BTarg.TargGoto(vector2d(400,300)),playerpos=BTarg.targpos; + if(!m19pldir&&GetDist(playerpos,vector2d(400,300))<0.01)m19pldir=true; + for(int i=0;i<m19cnt;++i) + { + if(bullet[m19gen[i]].redattrib) + { + if(bullet[m19gen[i]].redattrib>1) + { + double r=re.NextDouble(0,75-50*(frameleft/(double)(AMinute*2))),theta=re.NextDouble(-pi,pi); + bullet[m19gen[i]].bulletpos=vector2d(400+r*cos(theta),300+r*sin(theta)); + bullet[m19gen[i]].bulletspeed=0; + } + else + { + if(GetDist(bullet[m19gen[i]].bulletpos,vector2d(400,300))<4) + { + bullet[m19gen[i]].redattrib=2; + bullet[m19gen[i]].setdir(re.NextDouble(-pi,pi)); + bullet[m19gen[i]].bulletaccel=0.0015; + bullet[m19gen[i]].limv=re.NextDouble(1,8-2*(frameleft/(double)(AMinute*2))); + } + } + } + } +} +void Levelm1Part14() +{ + avacurbrk+=hge->Timer_GetDelta(); + m19rad+=pi/(5400.0f+1800.0f*(frameleft/(double)(AMinute*2)))*(1000.0f/hge->Timer_GetFPS()); + for(int i=0;i<8;++i)bullet[m19lead[i]].bulletpos=vector2d(400+250*cos(m19rad+i*pi/4),300+250*sin(m19rad+i*pi/4)); + switch(m19step) + { + case 0: + if(avacurbrk>avabrk) + { + for(int i=0;i<8;++i) + { + m19gen[m19cnt]=CreateBullet2(bullet[m19lead[i]].bulletpos.x,bullet[m19lead[i]].bulletpos.y,0,0); + bullet[m19gen[m19cnt]].redir(vector2d(400,300)); + bullet[m19gen[m19cnt]].alterColor=(TColors)i; + bullet[m19gen[m19cnt]].bulletaccel=0.002; + bullet[m19gen[m19cnt]].limv=3; + bullet[m19gen[m19cnt]].whirem=1000; + bullet[m19gen[m19cnt]].addblend=true; + bullet[m19gen[m19cnt++]].redattrib=re.NextInt(0,3)?0:1; + } + if(m19cnt/8>80-50*(frameleft/(double)(AMinute*2)))m19step=1,avabrk=3,tbrk=0; + avacurbrk=0; + } + Levelm1Part20update(); + break; + case 1: + if(avacurbrk>avabrk) + { + m19step=0;avabrk=0.05;memset(m19gen,0,sizeof(m19gen));m19cnt=0; + } + tbrk+=hge->Timer_GetDelta(); + if(tbrk>0.05) + { + tbrk=0; + for(int i=0;i<8;++i) + { + int pnt=CreateBullet2(bullet[m19lead[i]].bulletpos.x,bullet[m19lead[i]].bulletpos.y,0,0); + bullet[pnt].redir(vector2d(400,300)); + bullet[pnt].alterColor=(TColors)i; + bullet[pnt].bulletdir.x=-bullet[pnt].bulletdir.x; + bullet[pnt].bulletdir.y=-bullet[pnt].bulletdir.y; + bullet[pnt].bulletaccel=0.002;bullet[pnt].limv=2; + bullet[pnt].whirem=2500;bullet[pnt].addblend=true; + } + } + Levelm1Part20update(); + break; + } +} +vector2d snextarg; +int snexcnt,snexstep; +Target snexTarg; +void Levelm1Part15()//"Supernova" +{ + frameleft=AMinute*2;clrtime=1; + ++bgbrk;if (LOWFPS)bgbrk+=16; + if (bgbrk<30)return; + bgbrk=0;towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Super...\n\ +...nova!!"); + return; + } + if (Current_Position==1) + { + snexTarg.Init(0.001,vector2d(400,300)); + All2pnt(); + ++part;avabrk=12.0f;avacurbrk=0;tbrk=0; + snexstep=0;snexcnt=10;snexTarg.TargShow(); + } +} +void snCircCreator(vector2d p,int cnt,TColors col,bool mode) +{ + if(mode) + for (int i=0;i<cnt;++i) + { + int pnt=CreateBullet2(p.x,p.y,6,acos((playerpos-vector2d(400,300))^vector2d(1,0))+(i-0.5f)*(2*pi/cnt)); + bullet[pnt].redir(playerpos);bullet[pnt].bulletdir.Rotate((i+0.5f)*(2*pi/cnt)); + bullet[pnt].alterColor=col;bullet[pnt].addblend=true; + } + else + for (int i=0;i<cnt;++i) + { + int pnt=CreateBullet2(p.x,p.y,2,acos((playerpos-vector2d(400,300))^vector2d(1,0))+i*(2*pi/cnt)); + bullet[pnt].redir(playerpos);bullet[pnt].bulletdir.Rotate(i*(2*pi/cnt)); + bullet[pnt].alterColor=col;bullet[pnt].addblend=true; + } +} +void Levelm1Part16() +{ + snexTarg.TargRender(); + avacurbrk+=hge->Timer_GetDelta(); + tbrk+=hge->Timer_GetDelta(); + if((AMinute*2-frameleft)<TenSeconds) + { + if(tbrk>0.016&&(AMinute*2-frameleft)>TenSeconds/5) + { + tbrk=0; + snCircCreator(vector2d(400,300),144,(TColors)re.NextInt(0,7),true); + } + } + else + { + if(tbrk>0.5) + { + tbrk=0; + snCircCreator(vector2d(400,300),27,(TColors)re.NextInt(0,7),false); + } + } + switch (snexstep) + { + case 0: + if(avacurbrk>avabrk)snexstep=1,snextarg=playerpos; + break; + case 1: + snexTarg.TargGoto(snextarg); + if(GetDist(snexTarg.targpos,snextarg)<0.01) + { + snexstep=2; + avabrk=(frameleft/(double)(AMinute*2))*0.01666+0.01667; + avacurbrk=0; + snexcnt=40-(frameleft/(double)(AMinute*2))*20; + } + break; + case 2: + if(avacurbrk>avabrk) + { + if(--snexcnt>0) + { + avacurbrk=0; + for(int i=0;i<10;++i) + bullet[CreateBullet2(snexTarg.targpos.x,snexTarg.targpos.y,2,re.NextDouble(-pi,pi),true)].addblend=true; + } + else snexstep=0,avabrk=(frameleft/(double)(AMinute*2))*1+1.5f,avacurbrk=0; + } + break; + } +} +yellowGroup fyg[100]; +//Spinner fygs; +void Levelm1Part17() +{ + frameleft=AMinute+ThirtySeconds;clrtime=2; + All2pnt();towcnt=0;memset(fyg,0,sizeof(fyg)); + ++part;avabrk=1;avacurbrk=0.5;//fygs.Init(3,20); +} +void Levelm1Part18() +{ + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk) + { + avacurbrk=0; + for(int i=0;i<100;++i) + if(!fyg[i].isActive()) + { + if(frameleft>AMinute) + fyg[i].Init(12,2.5-1.5*(frameleft/(double)(AMinute+ThirtySeconds))); + else + fyg[i].Init(36,2.5-1.5*(frameleft/(double)(AMinute+ThirtySeconds))); + break; + } + CircCreator(vector2d(400,300),36,blue); + } + for(int i=0;i<100;++i)if(fyg[i].isActive())fyg[i].Update(); + //fygs.Update(pi/7200*(0.5+frameleft/(double)(AMinute+ThirtySeconds))); +} +int m17lead[4]; +void Levelm1Part19() +{ + frameleft=AMinute+ThirtySeconds;towcnt=0;clrtime=1; + All2pnt();memset(m17lead,0,sizeof(m17lead)); + ++part;avabrk=0; + m17lead[0]=CreateBullet2(10,10,4,0);bullet[m17lead[0]].redir(vector2d(780,10));bullet[m17lead[0]].alterColor=red; + m17lead[1]=CreateBullet2(780,10,4,0);bullet[m17lead[1]].redir(vector2d(780,580));bullet[m17lead[1]].alterColor=green; + m17lead[2]=CreateBullet2(780,580,4,0);bullet[m17lead[2]].redir(vector2d(10,580));bullet[m17lead[2]].alterColor=dblue; + m17lead[3]=CreateBullet2(10,580,4,0);bullet[m17lead[3]].redir(vector2d(10,10));bullet[m17lead[3]].alterColor=white; + for(int i=0;i<4;++i)bullet[m17lead[i]].inv=true;snexTarg.Init(0.001,vector2d(400,300)); + snexstep=0;snexTarg.TargShow();avabrk=5.0f;avacurbrk=0;tbrk=0; +} +void Levelm1Part20() +{ + snexTarg.TargRender();avacurbrk+=hge->Timer_GetDelta(); + tbrk+=hge->Timer_GetDelta();avabrk+=hge->Timer_GetDelta(); + if(avabrk>10)NewMultpo(),avabrk=0; + switch (snexstep) + { + case 0: + if(avacurbrk>avabrk)snexstep=1,snextarg=playerpos; + break; + case 1: + snexTarg.TargGoto(snextarg); + if(GetDist(snexTarg.targpos,snextarg)<0.01) + { + snexstep=0; + avabrk=(frameleft/(double)(AMinute*2))*3+2; + avacurbrk=0; + } + break; + } + if(bullet[m17lead[0]].bulletpos.x>780.01f)bullet[m17lead[0]].bulletpos=vector2d(780,10),bullet[m17lead[0]].redir(vector2d(780,580)); + if(bullet[m17lead[0]].bulletpos.y>580.01f)bullet[m17lead[0]].bulletpos=vector2d(780,580),bullet[m17lead[0]].redir(vector2d(10,580)); + if(bullet[m17lead[0]].bulletpos.x<9.99f)bullet[m17lead[0]].bulletpos=vector2d(10,580),bullet[m17lead[0]].redir(vector2d(10,10)); + if(bullet[m17lead[0]].bulletpos.y<9.99f)bullet[m17lead[0]].bulletpos=vector2d(10,10),bullet[m17lead[0]].redir(vector2d(780,10)); + + if(bullet[m17lead[1]].bulletpos.x>780.01)bullet[m17lead[1]].bulletpos=vector2d(780,10),bullet[m17lead[1]].redir(vector2d(780,580)); + if(bullet[m17lead[1]].bulletpos.y>580.01f)bullet[m17lead[1]].bulletpos=vector2d(780,580),bullet[m17lead[1]].redir(vector2d(10,580)); + if(bullet[m17lead[1]].bulletpos.x<9.99f)bullet[m17lead[1]].bulletpos=vector2d(10,580),bullet[m17lead[1]].redir(vector2d(10,10)); + if(bullet[m17lead[1]].bulletpos.y<9.99f)bullet[m17lead[1]].bulletpos=vector2d(10,10),bullet[m17lead[1]].redir(vector2d(780,10)); + + if(bullet[m17lead[2]].bulletpos.x>780.01f)bullet[m17lead[2]].bulletpos=vector2d(780,10),bullet[m17lead[2]].redir(vector2d(780,580)); + if(bullet[m17lead[2]].bulletpos.y>580.01f)bullet[m17lead[2]].bulletpos=vector2d(780,580),bullet[m17lead[2]].redir(vector2d(10,580)); + if(bullet[m17lead[2]].bulletpos.x<9.99f)bullet[m17lead[2]].bulletpos=vector2d(10,580),bullet[m17lead[2]].redir(vector2d(10,10)); + if(bullet[m17lead[2]].bulletpos.y<9.99f)bullet[m17lead[2]].bulletpos=vector2d(10,10),bullet[m17lead[2]].redir(vector2d(780,10)); + + if(bullet[m17lead[3]].bulletpos.x>780.01f)bullet[m17lead[3]].bulletpos=vector2d(780,10),bullet[m17lead[3]].redir(vector2d(780,580)); + if(bullet[m17lead[3]].bulletpos.y>580.01f)bullet[m17lead[3]].bulletpos=vector2d(780,580),bullet[m17lead[3]].redir(vector2d(10,580)); + if(bullet[m17lead[3]].bulletpos.x<9.99f)bullet[m17lead[3]].bulletpos=vector2d(10,580),bullet[m17lead[3]].redir(vector2d(10,10)); + if(bullet[m17lead[3]].bulletpos.y<9.99f)bullet[m17lead[3]].bulletpos=vector2d(10,10),bullet[m17lead[3]].redir(vector2d(780,10)); + if(tbrk>0.02+(frameleft/(double)(AMinute+ThirtySeconds))*0.08) + { + for(int i=0;i<4;++i) + { + int pnt=CreateBullet2(bullet[m17lead[i]].bulletpos.x,bullet[m17lead[i]].bulletpos.y,0,0,true); + bullet[pnt].redir(snexTarg.targpos); + bullet[pnt].bulletaccel=0.002;bullet[pnt].limv=3; + bullet[pnt].whirem=1500-(frameleft/(double)(AMinute+ThirtySeconds))*500; + bullet[pnt].alterColor=i==0?red:i==1?green:i==2?dblue:white; + } + tbrk=0; + } +} +void Levelm1Part21() +{ + //some part of this level is in towernbullet... + frameleft=AMinute*1.5;clrtime=1; + if (towcnt!=4&&towcnt!=0)return ClearAll(false); + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Zzz..."); + All2pnt(); + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + CreateTower8(30,10,1500,3,20,30,false); + CreateTower8(746,10,1500,3,20,30,false); + CreateTower8(30,556,1500,3,20,30,false); + CreateTower8(746,556,1500,3,20,30,false); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + IfCallLevel=false; + return; + } +} +void Levelm2Part0() +{ + frameleft=10;All2pnt();towcnt=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("\ +Level -2-Assessments\n\ +Welcome to assessment mode!\n\ +You won't step to the next level until\n\ +you have a collision.\n\ +Good luck and go for the highest score!\ +"); + } + if (Current_Position==1) + { + if((DBGColor=ColorTransfer(DBGColor,0xFF1B2065))!=0xFF1B2065) + DBGColor=ColorTransfer(DBGColor,0xFF1B2065),frameleft=10; + else{++part;IfShowTip=true;bulcnt=0;return;} + } +} +Tower* dbtows[200]; +double dbroll[10]; +void Levelm2Part1() +{ + frameleft=Infinity;tbrk=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 1 - Directed bullet"); + return; + } + for(int i=0;i<5;++i) + { + dbroll[i]=-i*120-20; + for(int j=0;j<20;++j) + dbtows[i*20+j]=&tower[CreateTower1(j*40+10,dbroll[i],4000,4)]; + } + ++part; +} +void Levelm2Part2() +{ + frameleft=Infinity; + tbrk+=hge->Timer_GetDelta(); + for(int i=0;i<5;++i) + { + dbroll[i]+=0.05*(1000.0f/hge->Timer_GetFPS()); + if(dbroll[i]>600)dbroll[i]=-20; + for(int j=0;j<20;++j) + { + dbtows[i*20+j]->towerpos=vector2d(j*40+10,dbroll[i]); + if(tbrk>0.033&&dbtows[i*20+j]->towertimer>2000)dbtows[i*20+j]->towertimer-=2; + } + } + if(tbrk>0.033)tbrk=0; +} +void Levelm2Part3() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 2 - Random bullets"); + All2pnt(); + return; + } + if (towcnt!=1&&towcnt!=0)return ClearAll(false); + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + CreateTower2(400,300,999999999,0); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else + { + ++part;assetime=tbrk=0; + return; + } +} +int rcnt; +void Levelm2Part4() +{ + frameleft=Infinity; + tbrk-=hge->Timer_GetDelta(); + if(tbrk<0) + { + tbrk=0.5; + if(assetime>=5)tbrk=re.NextDouble(0.25,0.5); + if(assetime>=10)tbrk=re.NextDouble(0.1,0.2); + if(assetime>=20)tbrk=re.NextDouble(0.05,0.08); + if(assetime>=30)tbrk=re.NextDouble(0.02,0.035); + if(assetime>=60)tbrk=0.02;if(assetime>=90)tbrk=0.01; + if(assetime<90)rcnt=1;if(assetime>=90)rcnt=2; + if(assetime>=120)rcnt=4;if(assetime>=150)rcnt=8; + if(assetime>=180)rcnt=16; + double rspeed=re.NextDouble(0.5+3*assetime/180.0f,1+9*assetime/180.0f); + for(int i=0;i<rcnt;++i) + CreateBullet2(400,300,rspeed,re.NextDouble(-pi,pi)); + } +} + +expSpinner es; +void Levelm2Part5() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 3 - Constant patterns"); + All2pnt(); + return; + } + if (towcnt!=0)return ClearAll(false); + if(Current_Position==1) + { + ++part;avabrk=0;avacurbrk=0; + } +} +void Levelm2Part6() +{ + frameleft=Infinity; + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk) + { + avacurbrk=0; + avabrk=6-2*assetime/120.0f; + if(avabrk<3)avabrk=1; + es.Init(3+5*assetime/120.0f,10,re.NextInt(-pi,pi)); + } + if(es.isActive())es.Update(); +} + +BCircle asscircles[200]; +void Levelm2Part7() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 4 - Crossing 1"); + All2pnt(); + return; + } + if (towcnt!=0)return ClearAll(false); + if(Current_Position==1) + { + memset(asscircles,0,sizeof(asscircles)); + ++part;avabrk=0;avacurbrk=0; + } +} +void Levelm2Part8() +{ + frameleft=Infinity; + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk) + { + shots=1; + for(int i=0;i<200;++i) + if (asscircles[i].GetRange()>800||asscircles[i].GetRange()<1e-7) + { + asscircles[i].Init(1,assetime/120.0f*0.00025,36,vector2d(250,300),blue);break; + } + for(int i=0;i<200;++i) + if (asscircles[i].GetRange()>800||asscircles[i].GetRange()<1e-7) + { + asscircles[i].Init(1,-assetime/120.0f*0.00025,36,vector2d(550,300),blue);break; + } + avacurbrk=0; + avabrk=3-assetime/60; + if(avabrk<0.5)avabrk=0.5; + } + for(int i=0;i<200;++i) + { + if (asscircles[i].GetRange()>1e-7&&asscircles[i].GetRange()<800) + { + asscircles[i].SetRange(asscircles[i].GetRange()+(LOWFPS?17:1)*0.05); + asscircles[i].Update(); + } + } +} +void Levelm2Part9() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 5 - Crossing 2"); + for(int i=0;i<200;++i) + if (asscircles[i].GetRange()>1e-7&&asscircles[i].GetRange()<800) + asscircles[i].circ2pnt(); + return; + } + if(Current_Position==1) + { + memset(asscircles,0,sizeof(asscircles)); + ++part;avabrk=0;avacurbrk=0; + } +} +void Levelm2Part10() +{ + frameleft=Infinity; + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk) + { + shots=1; + for(int i=0;i<200;++i) + if (asscircles[i].GetRange()>800||asscircles[i].GetRange()<1e-7) + { + asscircles[i].Init(1,0.0001,36+(24*assetime/120.0f),vector2d(400,300),blue);break; + } + for(int i=0;i<200;++i) + if (asscircles[i].GetRange()>800||asscircles[i].GetRange()<1e-7) + { + asscircles[i].Init(1,-0.0001,36+(24*assetime/120.0f),vector2d(400,300),blue);break; + } + avacurbrk=0; + avabrk=2-assetime/60; + if(avabrk<0.3)avabrk=0.3; + } + for(int i=0;i<200;++i) + { + if (asscircles[i].GetRange()>1e-7&&asscircles[i].GetRange()<800) + { + asscircles[i].SetRange(asscircles[i].GetRange()+(LOWFPS?17:1)*0.05); + asscircles[i].Update(); + } + } +} +double assrad; +SELineLaser trap[100]; +void Levelm2Part11() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 6 - Trappy"); + for(int i=0;i<200;++i) + if (asscircles[i].GetRange()>1e-7&&asscircles[i].GetRange()<800) + asscircles[i].circ2pnt(); + return; + } + if(Current_Position==1) + { + memset(asscircles,0,sizeof(asscircles)); + ++part;avabrk=0;avacurbrk=0;tbrk=0;memset(trap,0,sizeof(trap)); + } +} +void Levelm2Part12() +{ + frameleft=Infinity; + avacurbrk+=hge->Timer_GetDelta(); + for(int i=0;i<100;++i) + if(trap[i].isActive())trap[i].Update(); + if(avacurbrk>avabrk) + { + bool sh=re.NextInt(0,1); + for(int c=0;c<(assetime>30?(assetime-30)/30:1);++c,sh^=1) + for(int i=0;i<100;++i) + if(!trap[i].isActive()) + { + if(sh)trap[i].Init(re.NextInt(10,590),1); + else trap[i].Init(re.NextInt(10,790),0); + break; + } + avacurbrk=0; + if(assetime<60)avabrk=3-2*assetime/60.0f; + else avabrk=2.5-(assetime-60)/120.0f; + } +} +double asssrd1; +void Levelm2Part13() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 7 - Sine wave"); + All2pnt(); + return; + } + if (towcnt!=0)return ClearAll(false); + if(Current_Position==1) + { + ++part;tbrk=asssrd1=avacurbrk=0; + } +} +void Levelm2Part14() +{ + frameleft=Infinity; + tbrk+=hge->Timer_GetDelta(); + if(tbrk>0.075) + { + tbrk=0; + asssrd1+=pi/45; + //right + for(int i=0;i<5;++i) + CreateBullet2(810,120*(i+1)+120*sin(asssrd1),2,0,true); + //right2 + if(assetime>15) + { + for(int i=0;i<5;++i) + CreateBullet2(810,120*(i+1)+120*sin(asssrd1+pi/12),2,0,true); + } + //left + if(assetime>30) + { + for(int i=0;i<5;++i) + CreateBullet2(-10,120*(i+1)+120*sin(asssrd1),2,pi,true); + } + //left2 + if(assetime>45) + { + for(int i=0;i<5;++i) + CreateBullet2(-10,120*(i+1)+120*sin(asssrd1+pi/12),2,pi,true); + } + if(assetime>60) + { + avacurbrk-=hge->Timer_GetDelta(); + if(avacurbrk<0) + { + CreateBullet1(0,0,3,0);CreateBullet1(800,0,3,0); + CreateBullet1(0,600,3,0);CreateBullet1(800,600,3,0); + avacurbrk=0.5-0.3*(assetime-60.0f)/60.0f; + if(avacurbrk<0.1)avacurbrk=0.1; + } + } + } +} +int resvpos,rpbcnt; +double delx; +void Levelm2Part15() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 8 - Density test"); + All2pnt(); + return; + } + if (towcnt!=0)return ClearAll(false); + if(Current_Position==1) + { + ++part;tbrk=asssrd1=avacurbrk=0;resvpos=re.NextInt(0,49);rpbcnt=0; + } +} +void Levelm2Part16() +{ + frameleft=Infinity; + tbrk-=hge->Timer_GetDelta(); + if(tbrk<0) + { + tbrk=0.1-0.05*(assetime/120.0f);if(tbrk<0.05)tbrk=0.05; + if(re.NextInt(0,100)==37&&!rpbcnt) + { + rpbcnt=6;int oldrp=resvpos; + for(resvpos=re.NextInt(0,49);abs(resvpos-oldrp)>20||abs(resvpos-oldrp)<5;resvpos=re.NextInt(0,49)); + delx=re.NextDouble(300,650); + } + for(int i=0;i<50;++i) + { + if(abs(i-resvpos)>2) + { + int pnt=CreateBullet2(810,12*i,1+3*assetime/180.0f,0,true); + if(rpbcnt>0)bullet[pnt].limpos=vector2d(delx,12*i); + } + } + if(rpbcnt)--rpbcnt; + if(resvpos==0)resvpos+=re.NextInt(0,1); + else if(resvpos==49)resvpos+=re.NextInt(-1,0); + else resvpos+=re.NextInt(-1,1); + } +} +CPinBall pinballs[200]; +void Levelm2Part17() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 9 - Pinball"); + All2pnt(); + return; + } + if (towcnt!=0)return ClearAll(false); + if(Current_Position==1) + { + ++part;tbrk=0;memset(pinballs,0,sizeof(pinballs)); + } +} +void Levelm2Part18() +{ + frameleft=Infinity; + //Always clean up! + for(int i=0;i<200;++i)if(pinballs[i].Getlifetime()>5)pinballs[i].Kill(); + tbrk-=hge->Timer_GetDelta(); + if(tbrk<0) + { + tbrk=1.25-0.5*assetime/120.0f;if(tbrk<0.5)tbrk=0.5; + for(int i=0;i<200;++i) + if(pinballs[i].Getlifetime()==0) + { + int lay=4+4*assetime/120.0f;if(lay>8)lay=9; + lay=re.NextInt(3,lay); + vector2d pos; + while(1) + { + pos=vector2d(re.NextDouble(100,600),re.NextDouble(100,500)); + bool place=(GetDist(pos,playerpos)>=100); + for(int j=0;j<200;++j) + if(pinballs[j].Getlifetime()>0&&j!=i) + if(GetDist(pinballs[j].Position(),pos)<pinballs[j].Radius()+lay*10.0) + {place=false;break;} + if(place)break; + } + pinballs[i].Init(pos,lay); + break; + } + } + for(int i=0;i<200;++i) + if(pinballs[i].Getlifetime()>0) + { + vector2d pos=pinballs[i].Position(); + if(pos.x<pinballs[i].Radius()-5||pos.x>790-pinballs[i].Radius()) + pinballs[i].Delta().x=-pinballs[i].Delta().x,++pinballs[i].Getlifetime(),pinballs[i].UpdateDelta(); + if(pos.y<pinballs[i].Radius()-5||pos.y>590-pinballs[i].Radius()) + pinballs[i].Delta().y=-pinballs[i].Delta().y,++pinballs[i].Getlifetime(),pinballs[i].UpdateDelta(); + for(int j=i+1;j<200;++j) + if(pinballs[j].Getlifetime()>0&&pinballs[j].Getlifetime()<=5) + if(GetDist(pinballs[j].Position(),pinballs[i].Position())<pinballs[j].Radius()+pinballs[i].Radius()) + { + double sqrdis=sqr(GetDist(pinballs[j].Position(),pinballs[i].Position())); + vector2d colline(pinballs[j].Position().x-pinballs[i].Position().x, + pinballs[j].Position().y-pinballs[i].Position().y); + double vp=pinballs[i].Delta()|colline; + double wp=pinballs[j].Delta()|colline; + vector2d ddelta((wp-vp)*colline.x/sqrdis,(wp-vp)*colline.y/sqrdis); + pinballs[i].Delta().x+=ddelta.x;pinballs[i].Delta().y+=ddelta.y; + pinballs[j].Delta().x-=ddelta.x;pinballs[j].Delta().y-=ddelta.y; + //prevent them to stick together... + vector2d stkprv=0.05*(pinballs[j].Radius()/sqrt(sqrdis)-1)*colline; + pinballs[j].Position()=pinballs[j].Position()-stkprv; + pinballs[i].UpdateDelta();pinballs[j].UpdateDelta(); + } + pinballs[i].Update(); + } +} +void Levelm2Part19() +{ + frameleft=Infinity; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 10 - Road blocks"); + All2pnt(); + return; + } + if (towcnt!=0)return ClearAll(false); + if(Current_Position==1) + { + ++part;tbrk=0;memset(pinballs,0,sizeof(pinballs)); + } +} +void Levelm2Part20() +{ + frameleft=Infinity; + tbrk-=hge->Timer_GetDelta(); + if(tbrk<0) + { + tbrk=2-1*(assetime/120.0f);if(tbrk<0.75)tbrk=0.75; + delx=re.NextDouble(350,700); + resvpos=re.NextInt(0,49); + for(int i=0;i<50;++i) + { + int pnt=CreateBullet2(810,12*i,1+2*assetime/180.0f,0,true); + if(abs(i-resvpos)<=3)bullet[pnt].limpos=vector2d(delx,12*i); + } + } +} +void Levelm2Part21() +{ + frameleft=Infinity;Dis8ref=true;tbrk=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 11 - Extreme speeds"); + All2pnt();towcnt=0; + return; + } + ++frameskips; + if (frameskips<10&&!LOWFPS)return; + frameskips=0; + for (int i=1;i<=33;++i)CreateTower8(i*24-12,12,500,6,20,30); + for (int i=1;i<=towcnt;++i) + if (tower[i].RendColor==0x80FFFFFF) + tower[i].RendColor=0x00FFFFFF; + for (int i=1;i<=towcnt;++i) + if ((tower[i].RendColor>>24)<=0x80) + tower[i].RendColor=tower[i].RendColor+0x01FFFFFF; + else{++part;return;} +} +void Levelm2Part22() +{ + frameleft=Infinity; + double nspd=6+4*assetime/120.0f;if(nspd>10)nspd=10; + for(int i=1;i<=33;++i)tower[i].bulletspeed=nspd; + tbrk-=hge->Timer_GetDelta(); + if (tbrk>0)return; + tbrk=3-2*(assetime/120.0f); + if(tbrk<0.5)tbrk=0.5; + for (int i=0;i<6;++i) + { + int p=CreateBullet2(playerpos.x+cos(i*pi/3.0f)*6,12+sin(i*pi/3.0f)*6,2,-pi/2); + bullet[p].alterColor=orange; + } +} +SimpLL SLL[200]; +void Levelm2Part23() +{ + frameleft=Infinity;Dis8ref=true;tbrk=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Test 12 - Messed up"); + All2pnt();towcnt=0; + return; + } + if (towcnt!=0)return ClearAll(false); + ++part;tbrk=avacurbrk=avabrk=0;memset(SLL,0,sizeof(SLL)); +} +void Levelm2Part24() +{ + frameleft=Infinity; + tbrk-=hge->Timer_GetDelta(); + if(tbrk<0) + { + tbrk=3-2.5*(assetime/120.0f); + if(tbrk<0.5)tbrk=0.5; + /*int cnt=12+12*assetime/120.0f; + if(cnt>24)cnt=24; + for(int i=0;i<cnt;++i) + { + vector2d dir=vector2d(400-playerpos.x,300-playerpos.y); + dir.ToUnitCircle();dir=50*dir;dir.Rotate(i*2*pi/cnt); + int pnt=CreateBullet2(400+dir.x,300+dir.y,0,0,true); + bullet[pnt].limv=-2;bullet[pnt].bulletaccel=-0.001;bullet[pnt].whirem=500; + bullet[pnt].redir(vector2d(400,300)); + }*/ + } + avacurbrk+=hge->Timer_GetDelta(); + if(avacurbrk>avabrk) + { + avacurbrk=0;avabrk=4-3*assetime/120.0f;if(avabrk<0.5)avabrk=0.5; + vector2d a,b;int cnt=re.NextInt(5,10); + for (int i=0;i<cnt;++i) + { + if (re.NextInt(1,100)>=50) + { + if (re.NextInt(1,100)>=50)a=vector2d(re.NextDouble(10,790),610);else a=vector2d(re.NextDouble(10,790),-10); + } + else + { + if (re.NextInt(1,100)>=50)a=vector2d(-10,re.NextDouble(10,590));else a=vector2d(810,re.NextDouble(10,590)); + } + if (re.NextInt(1,100)>=50) + { + if (re.NextInt(1,100)>=50)b=vector2d(re.NextDouble(10,790),610);else b=vector2d(re.NextDouble(10,790),-10); + } + else + { + if (re.NextInt(1,100)>=50)b=vector2d(-10,re.NextDouble(10,590));else b=vector2d(810,re.NextDouble(10,590)); + } + for(int i=0;i<200;++i) + if(!SLL[i].active) + { + SLL[i].InitLine(a,b,0.1,SETA(ColorToDWORD(blue),0x80)); + SLL[i].active=true;SLL[i].stp=0;SLL[i].brk=0;SLL[i].EnableColl=false; + break; + } + } + } + for(int i=0;i<200;++i) + if(SLL[i].active) + { + SLL[i].Process(); + SLL[i].brk+=hge->Timer_GetDelta(); + if(SLL[i].stp==2) + if(SLL[i].brk>0.02) + { + SLL[i].SetWidth(SLL[i].GetWidth()-0.2); + if(SLL[i].GetWidth()<1)SLL[i].EnableColl=false; + if(SLL[i].GetWidth()<0.05)SLL[i].active=false; + SLL[i].brk=0; + } + if(SLL[i].stp==0) + if(SLL[i].brk>0.02) + { + SLL[i].SetWidth(SLL[i].GetWidth()+0.2); + if(SLL[i].GetWidth()>1)SLL[i].EnableColl=true; + if(SLL[i].GetWidth()>4)SLL[i].stp=1; + SLL[i].brk=0; + } + if(SLL[i].stp==1) + if(SLL[i].brk>5){SLL[i].brk=0;SLL[i].stp=2;} + } +} +void Levelm2Part25() +{ + frameleft=Infinity;Dis8ref=true;tbrk=0; + DisableAllTower=false; + if (IfShowTip) + { + IfShowTip=false; + FadeTip=false; + Current_Position=2; + ShowTip("Bonus test - Lunatic Lunar!"); + All2pnt();towcnt=0; + for(int i=0;i<200;++i)if(SLL[i].active)SLL[i].llsrtopnt(10); + return; + } + ++part;tbrk=0;memset(SLL,0,sizeof(SLL));avabrk=1; +} +void Levelm2Part26() +{ + frameleft=Infinity; + tbrk-=hge->Timer_GetDelta(); + if(tbrk<0) + { + tbrk=0.05; + int cnt=1; + if(!re.NextInt(0,19))avabrk=avabrk?0:1; + for(int i=0;i<cnt;++i) + { + if(avabrk) + { + int cc=assetime/120.0f*18+18; + vector2d centre(re.NextDouble(380,420),re.NextDouble(280,320)); + double rnd=atan2(playerpos.y-centre.y,playerpos.x-centre.x),spd=assetime/120.0f*4+6; + if(re.NextInt(0,3)) + rnd+=re.NextDouble(-assetime/120.0f*pi/24,assetime/120.0f*pi/24); + for(int i=0;i<cc;++i) + CreateBullet2(centre.x,centre.y,spd,i*2*pi/cc+rnd,false); + } + else + { + vector2d pos=vector2d(400+re.NextDouble(-20,20),300+re.NextDouble(-20,20)); + double spd=assetime/120.0f*4+6; + int cc=assetime/120.0f*18+18; + double rnd=atan2(playerpos.y-pos.y,playerpos.x-pos.x); + if(re.NextInt(0,3)) + rnd+=re.NextDouble(-assetime/120.0f*pi/24,assetime/120.0f*pi/24); + for(int i=0;i<cc;++i) + { + double dir=i*2*pi/cc+rnd,ran=re.NextDouble(-pi,pi); + for(int i=0;i<6;++i) + CreateBullet2(pos.x+6*sin(ran+i*(pi/3)),pos.y+6*cos(ran+i*(pi/3)),spd,dir,false); + CreateBullet2(pos.x,pos.y,spd,dir,false); + } + } + } + } +} diff --git a/archive/blr2/src/libcgh.h b/archive/blr2/src/libcgh.h new file mode 100644 index 0000000..324ba42 --- /dev/null +++ b/archive/blr2/src/libcgh.h @@ -0,0 +1,140 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Chrisoft Game Helper header +// Copyright Chrisoft 2014 +// libcgh version 0007 +// Last full compatible version 0007 +// ^Modify that when big change is made^ +#include <hge.h> +#include <hgefont.h> +#include <hgedistort.h> +#include <hgecolor.h> +#include <math.h> +#ifndef libcgh_H +#define libcgh_H +#define pi 3.1415926535 +#define sqr(x) ((x)*(x)) +//static const char* LIBCGH_H_FN="libcgh.h"; + +struct vector2d +{ + double x,y; + vector2d(double _x,double _y){x=_x;y=_y;} + vector2d(){x=y=0;} + double l(){return sqrt(sqr(x)+sqr(y));} + void ToUnitCircle(){double len=l();x/=len;y/=len;} + void Swap(){double t=x;x=y;y=t;} + void Rotate(double rad){double tx=x*cos(rad)+y*sin(rad),ty=y*cos(rad)-x*sin(rad);x=tx,y=ty;} + friend vector2d operator -(vector2d a,vector2d b) + { + return vector2d(a.x-b.x,a.y-b.y); + } + friend vector2d operator +(vector2d a,vector2d b) + { + return vector2d(a.x+b.x,a.y+b.y); + } + friend double operator |(vector2d a,vector2d b)//dot product + { + return a.x*b.x+a.y*b.y; + } + friend double operator *(vector2d a,vector2d b)//length of cross product + { + return a.x*b.y-b.x*a.y; + } + friend vector2d operator *(double a,vector2d b) + { + return vector2d(b.x*a,b.y*a); + } + friend double operator ^(vector2d a,vector2d b)//cosine of angle + { + return (a|b)/a.l()/b.l(); + } +}; +inline vector2d ToUnitCircle(vector2d input) +{ + vector2d res=input; + res.x=res.x/input.l(); + res.y=res.y/input.l(); + return res; +} +inline double GetDist(const vector2d a,const vector2d b) +{ + return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); +} +inline double GetDistSeg(const vector2d a,const vector2d b,const vector2d c) +{ + double l2=GetDist(a,b)*GetDist(a,b); + if (l2==0.0)return GetDist(c,a); + double t=((c-a)|(b-a))/l2; + if (t<0)return GetDist(c,a); + else if (t>1)return GetDist(c,b); + vector2d projection=a+t*(b-a); + return GetDist(c,projection); +} +inline double normalizerad(double a) +{ + while (a<0)a+=2*pi; + while (a>2*pi)a-=2*pi; + return a; +} +struct TextureRect +{ + double x,y,w,h; + TextureRect(){} + TextureRect(double _x,double _y,double _w,double _h){x=_x,y=_y,w=_w,h=_h;} +}; +class RandomEngine +{ +private: + unsigned int cseed; +public: + void SetSeed(unsigned int seed); + int NextInt(int min,int max); + double NextDouble(double min,double max); +}; +class CircleIndicator +{ +private: + hgeDistortionMesh *circle; + double value,radius,thk; + DWORD ccolour; + bool gradient; + BYTE alpha; +public: + void Init(double _r,double _thk,BYTE _a,bool _gr,HTEXTURE _Texture,TextureRect _TR,DWORD _cc=0); + void SetAlpha(BYTE _alpha); + void SetValue(double _value); + void Render(double x,double y); +}; +class LinearProgresser +{ +private: + double a,b,val; + double Elapsed,Limit; +public: + void Init(double _a,double _b,double _Lim); + void Launch(); + void Update(double DT); + double GetA(); + double GetB(); + double GetValue(); + double GetPercentage(); + double GetDelta(); + double GetElapsed(); +}; +class HangUpText +{ +private: + hgeFont *TFont; + vector2d Position; + double Elapsed,Limit,dlim,delta; + BYTE alim,alpha; + char Text[255]; + LinearProgresser Progresser,Progalpha; + bool done; +public: + bool Active(); + void Init(const char *Font,const char *_Text,double _tlim,double _alim,double _dlim,DWORD _color=0x00FFFFFF); + void Launch(vector2d pos); + void Process(double DT); +}; +#endif diff --git a/archive/blr2/src/libcghEx.cpp b/archive/blr2/src/libcghEx.cpp new file mode 100644 index 0000000..a8fa698 --- /dev/null +++ b/archive/blr2/src/libcghEx.cpp @@ -0,0 +1,113 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Chrisoft Game Helper Extras implementations +// Copyright Chrisoft 2014 +#include "libcgh.h" +#include <cmath> +#include <cstring> +//static const char* LIBCGH_SRC_FN="libcghEx.cpp"; + +void RandomEngine::SetSeed(unsigned int seed){cseed=seed;} +int RandomEngine::NextInt(int min,int max) +{ + if (min>max){int t=min;min=max;max=t;} + cseed*=214013;cseed+=2531011; + return min+(cseed^cseed>>15)%(max-min+1); +} +double RandomEngine::NextDouble(double min,double max) +{ + if (min>max){double t=min;min=max;max=t;} + cseed*=214013;cseed+=2531011; + return min+(cseed>>16)*(1.0f/65535.0f)*(max-min); +} +void CircleIndicator::Init(double _r,double _thk,BYTE _a,bool _gr,HTEXTURE _Texture,TextureRect _TR,DWORD _cc) +{ + circle=new hgeDistortionMesh(1025,3); + circle->SetTexture(_Texture); + circle->SetTextureRect(_TR.x,_TR.y,_TR.w,_TR.h); + radius=_r;thk=_thk;gradient=_gr;alpha=_a; + if (_gr)ccolour=SETA(0x00FF0000,alpha);else ccolour=_cc; + for (int i=0;i<=1024;++i) + { + double tang,tx,ty; + tang=(double)i/1024.0f*pi*2-pi/2; + tx=-cos(tang)*radius;ty=sin(tang)*radius; + circle->SetDisplacement(i,2,tx,ty,HGEDISP_TOPLEFT); + tx*=thk;ty*=thk; + circle->SetDisplacement(i,1,tx,ty,HGEDISP_TOPLEFT); + tx*=thk;ty*=thk; + circle->SetDisplacement(i,0,tx,ty,HGEDISP_TOPLEFT); + } +} +void CircleIndicator::SetAlpha(BYTE _alpha){alpha=_alpha;} +void CircleIndicator::SetValue(double _value) +{ + value=_value; + for (int i=0;i<=1024;++i) + { + int tr=(int)((1.0f-value)*255); + int tg=(int)(value*255); + DWORD tcolour=ARGB(alpha,tr,tg,0); + hgeColorHSV *tc=new hgeColorHSV(tcolour); + if (tc->v<0.85)tc->v=0.85; + if (gradient)tcolour=SETA(tc->GetHWColor(),alpha);else tcolour=SETA(ccolour,alpha); + if ((double)i/1024.0f<=value) + { + circle->SetColor(i,0,tcolour); + circle->SetColor(i,1,SETA(0x00FFFFFF,alpha)); + circle->SetColor(i,2,tcolour); + } + else + { + circle->SetColor(i,0,0x00000000); + circle->SetColor(i,1,0x00000000); + circle->SetColor(i,2,0x00000000); + } + delete tc; + } +} +void CircleIndicator::Render(double x,double y){circle->Render(x,y);} + +void LinearProgresser::Init(double _a,double _b,double _Lim){a=_a,b=_b,Limit=_Lim;} +void LinearProgresser::Launch(){Elapsed=0;val=a;} +void LinearProgresser::Update(double DT){if (Elapsed+DT>=Limit)return (void)(val=b,Elapsed=Limit);Elapsed+=DT;val=(b-a)*(Elapsed/Limit)+a;} +double LinearProgresser::GetValue(){return val;} +double LinearProgresser::GetA(){return a;} +double LinearProgresser::GetB(){return b;} +double LinearProgresser::GetPercentage(){return (Elapsed/Limit);} +double LinearProgresser::GetDelta(){return val-a;} +double LinearProgresser::GetElapsed(){return Elapsed;} + +bool HangUpText::Active(){return TFont&&!done;} +void HangUpText::Init(const char *Font,const char *_Text,double _tlim,double _alim,double _dlim,DWORD _color) +{ + TFont=new hgeFont(Font); + TFont->SetScale(0.8); + strcpy(Text,_Text); + Limit=_tlim;alim=_alim;dlim=_dlim;TFont->SetColor(_color); + Progresser.Init(0,dlim,Limit);Progalpha.Init(0,255,Limit/2); +} +void HangUpText::Launch(vector2d pos) +{ + Position=pos;Elapsed=0;delta=0;Progresser.Launch();Progalpha.Launch();done=false; +} +void HangUpText::Process(double DT) +{ + Progresser.Update(DT); + Position.y-=delta; + delta=Progresser.GetDelta(); + Position.y+=delta; + if (Progresser.GetElapsed()>Limit/2&&Progalpha.GetA()<Progalpha.GetB()) + { + Progalpha.Init(255,0,Limit/2); + Progalpha.Launch(); + } + if (Progalpha.GetA()>Progalpha.GetB()&&Progresser.GetElapsed()>=Limit) + { + delete TFont;TFont=0; + return (void)(done=true); + } + Progalpha.Update(DT); + if(!TFont)return; + TFont->SetColor(SETA(TFont->GetColor(),Progalpha.GetValue())); + TFont->printf(Position.x,Position.y,HGETEXT_CENTER,Text); +} diff --git a/archive/blr2/src/loading.h b/archive/blr2/src/loading.h new file mode 100644 index 0000000..acf59aa --- /dev/null +++ b/archive/blr2/src/loading.h @@ -0,0 +1,384 @@ +unsigned char Loading[]= +{0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x60, +0x00,0x00,0x00,0x20,0x08,0x06,0x00,0x00,0x00,0xED,0xC0,0x7D,0x54,0x00,0x00,0x00,0x09,0x70,0x48, +0x59,0x73,0x00,0x00,0x0B,0x13,0x00,0x00,0x0B,0x13,0x01,0x00,0x9A,0x9C,0x18,0x00,0x00,0x0A,0x4D, +0x69,0x43,0x43,0x50,0x50,0x68,0x6F,0x74,0x6F,0x73,0x68,0x6F,0x70,0x20,0x49,0x43,0x43,0x20,0x70, +0x72,0x6F,0x66,0x69,0x6C,0x65,0x00,0x00,0x78,0xDA,0x9D,0x53,0x77,0x58,0x93,0xF7,0x16,0x3E,0xDF, +0xF7,0x65,0x0F,0x56,0x42,0xD8,0xF0,0xB1,0x97,0x6C,0x81,0x00,0x22,0x23,0xAC,0x08,0xC8,0x10,0x59, +0xA2,0x10,0x92,0x00,0x61,0x84,0x10,0x12,0x40,0xC5,0x85,0x88,0x0A,0x56,0x14,0x15,0x11,0x9C,0x48, +0x55,0xC4,0x82,0xD5,0x0A,0x48,0x9D,0x88,0xE2,0xA0,0x28,0xB8,0x67,0x41,0x8A,0x88,0x5A,0x8B,0x55, +0x5C,0x38,0xEE,0x1F,0xDC,0xA7,0xB5,0x7D,0x7A,0xEF,0xED,0xED,0xFB,0xD7,0xFB,0xBC,0xE7,0x9C,0xE7, +0xFC,0xCE,0x79,0xCF,0x0F,0x80,0x11,0x12,0x26,0x91,0xE6,0xA2,0x6A,0x00,0x39,0x52,0x85,0x3C,0x3A, +0xD8,0x1F,0x8F,0x4F,0x48,0xC4,0xC9,0xBD,0x80,0x02,0x15,0x48,0xE0,0x04,0x20,0x10,0xE6,0xCB,0xC2, +0x67,0x05,0xC5,0x00,0x00,0xF0,0x03,0x79,0x78,0x7E,0x74,0xB0,0x3F,0xFC,0x01,0xAF,0x6F,0x00,0x02, +0x00,0x70,0xD5,0x2E,0x24,0x12,0xC7,0xE1,0xFF,0x83,0xBA,0x50,0x26,0x57,0x00,0x20,0x91,0x00,0xE0, +0x22,0x12,0xE7,0x0B,0x01,0x90,0x52,0x00,0xC8,0x2E,0x54,0xC8,0x14,0x00,0xC8,0x18,0x00,0xB0,0x53, +0xB3,0x64,0x0A,0x00,0x94,0x00,0x00,0x6C,0x79,0x7C,0x42,0x22,0x00,0xAA,0x0D,0x00,0xEC,0xF4,0x49, +0x3E,0x05,0x00,0xD8,0xA9,0x93,0xDC,0x17,0x00,0xD8,0xA2,0x1C,0xA9,0x08,0x00,0x8D,0x01,0x00,0x99, +0x28,0x47,0x24,0x02,0x40,0xBB,0x00,0x60,0x55,0x81,0x52,0x2C,0x02,0xC0,0xC2,0x00,0xA0,0xAC,0x40, +0x22,0x2E,0x04,0xC0,0xAE,0x01,0x80,0x59,0xB6,0x32,0x47,0x02,0x80,0xBD,0x05,0x00,0x76,0x8E,0x58, +0x90,0x0F,0x40,0x60,0x00,0x80,0x99,0x42,0x2C,0xCC,0x00,0x20,0x38,0x02,0x00,0x43,0x1E,0x13,0xCD, +0x03,0x20,0x4C,0x03,0xA0,0x30,0xD2,0xBF,0xE0,0xA9,0x5F,0x70,0x85,0xB8,0x48,0x01,0x00,0xC0,0xCB, +0x95,0xCD,0x97,0x4B,0xD2,0x33,0x14,0xB8,0x95,0xD0,0x1A,0x77,0xF2,0xF0,0xE0,0xE2,0x21,0xE2,0xC2, +0x6C,0xB1,0x42,0x61,0x17,0x29,0x10,0x66,0x09,0xE4,0x22,0x9C,0x97,0x9B,0x23,0x13,0x48,0xE7,0x03, +0x4C,0xCE,0x0C,0x00,0x00,0x1A,0xF9,0xD1,0xC1,0xFE,0x38,0x3F,0x90,0xE7,0xE6,0xE4,0xE1,0xE6,0x66, +0xE7,0x6C,0xEF,0xF4,0xC5,0xA2,0xFE,0x6B,0xF0,0x6F,0x22,0x3E,0x21,0xF1,0xDF,0xFE,0xBC,0x8C,0x02, +0x04,0x00,0x10,0x4E,0xCF,0xEF,0xDA,0x5F,0xE5,0xE5,0xD6,0x03,0x70,0xC7,0x01,0xB0,0x75,0xBF,0x6B, +0xA9,0x5B,0x00,0xDA,0x56,0x00,0x68,0xDF,0xF9,0x5D,0x33,0xDB,0x09,0xA0,0x5A,0x0A,0xD0,0x7A,0xF9, +0x8B,0x79,0x38,0xFC,0x40,0x1E,0x9E,0xA1,0x50,0xC8,0x3C,0x1D,0x1C,0x0A,0x0B,0x0B,0xED,0x25,0x62, +0xA1,0xBD,0x30,0xE3,0x8B,0x3E,0xFF,0x33,0xE1,0x6F,0xE0,0x8B,0x7E,0xF6,0xFC,0x40,0x1E,0xFE,0xDB, +0x7A,0xF0,0x00,0x71,0x9A,0x40,0x99,0xAD,0xC0,0xA3,0x83,0xFD,0x71,0x61,0x6E,0x76,0xAE,0x52,0x8E, +0xE7,0xCB,0x04,0x42,0x31,0x6E,0xF7,0xE7,0x23,0xFE,0xC7,0x85,0x7F,0xFD,0x8E,0x29,0xD1,0xE2,0x34, +0xB1,0x5C,0x2C,0x15,0x8A,0xF1,0x58,0x89,0xB8,0x50,0x22,0x4D,0xC7,0x79,0xB9,0x52,0x91,0x44,0x21, +0xC9,0x95,0xE2,0x12,0xE9,0x7F,0x32,0xF1,0x1F,0x96,0xFD,0x09,0x93,0x77,0x0D,0x00,0xAC,0x86,0x4F, +0xC0,0x4E,0xB6,0x07,0xB5,0xCB,0x6C,0xC0,0x7E,0xEE,0x01,0x02,0x8B,0x0E,0x58,0xD2,0x76,0x00,0x40, +0x7E,0xF3,0x2D,0x8C,0x1A,0x0B,0x91,0x00,0x10,0x67,0x34,0x32,0x79,0xF7,0x00,0x00,0x93,0xBF,0xF9, +0x8F,0x40,0x2B,0x01,0x00,0xCD,0x97,0xA4,0xE3,0x00,0x00,0xBC,0xE8,0x18,0x5C,0xA8,0x94,0x17,0x4C, +0xC6,0x08,0x00,0x00,0x44,0xA0,0x81,0x2A,0xB0,0x41,0x07,0x0C,0xC1,0x14,0xAC,0xC0,0x0E,0x9C,0xC1, +0x1D,0xBC,0xC0,0x17,0x02,0x61,0x06,0x44,0x40,0x0C,0x24,0xC0,0x3C,0x10,0x42,0x06,0xE4,0x80,0x1C, +0x0A,0xA1,0x18,0x96,0x41,0x19,0x54,0xC0,0x3A,0xD8,0x04,0xB5,0xB0,0x03,0x1A,0xA0,0x11,0x9A,0xE1, +0x10,0xB4,0xC1,0x31,0x38,0x0D,0xE7,0xE0,0x12,0x5C,0x81,0xEB,0x70,0x17,0x06,0x60,0x18,0x9E,0xC2, +0x18,0xBC,0x86,0x09,0x04,0x41,0xC8,0x08,0x13,0x61,0x21,0x3A,0x88,0x11,0x62,0x8E,0xD8,0x22,0xCE, +0x08,0x17,0x99,0x8E,0x04,0x22,0x61,0x48,0x34,0x92,0x80,0xA4,0x20,0xE9,0x88,0x14,0x51,0x22,0xC5, +0xC8,0x72,0xA4,0x02,0xA9,0x42,0x6A,0x91,0x5D,0x48,0x23,0xF2,0x2D,0x72,0x14,0x39,0x8D,0x5C,0x40, +0xFA,0x90,0xDB,0xC8,0x20,0x32,0x8A,0xFC,0x8A,0xBC,0x47,0x31,0x94,0x81,0xB2,0x51,0x03,0xD4,0x02, +0x75,0x40,0xB9,0xA8,0x1F,0x1A,0x8A,0xC6,0xA0,0x73,0xD1,0x74,0x34,0x0F,0x5D,0x80,0x96,0xA2,0x6B, +0xD1,0x1A,0xB4,0x1E,0x3D,0x80,0xB6,0xA2,0xA7,0xD1,0x4B,0xE8,0x75,0x74,0x00,0x7D,0x8A,0x8E,0x63, +0x80,0xD1,0x31,0x0E,0x66,0x8C,0xD9,0x61,0x5C,0x8C,0x87,0x45,0x60,0x89,0x58,0x1A,0x26,0xC7,0x16, +0x63,0xE5,0x58,0x35,0x56,0x8F,0x35,0x63,0x1D,0x58,0x37,0x76,0x15,0x1B,0xC0,0x9E,0x61,0xEF,0x08, +0x24,0x02,0x8B,0x80,0x13,0xEC,0x08,0x5E,0x84,0x10,0xC2,0x6C,0x82,0x90,0x90,0x47,0x58,0x4C,0x58, +0x43,0xA8,0x25,0xEC,0x23,0xB4,0x12,0xBA,0x08,0x57,0x09,0x83,0x84,0x31,0xC2,0x27,0x22,0x93,0xA8, +0x4F,0xB4,0x25,0x7A,0x12,0xF9,0xC4,0x78,0x62,0x3A,0xB1,0x90,0x58,0x46,0xAC,0x26,0xEE,0x21,0x1E, +0x21,0x9E,0x25,0x5E,0x27,0x0E,0x13,0x5F,0x93,0x48,0x24,0x0E,0xC9,0x92,0xE4,0x4E,0x0A,0x21,0x25, +0x90,0x32,0x49,0x0B,0x49,0x6B,0x48,0xDB,0x48,0x2D,0xA4,0x53,0xA4,0x3E,0xD2,0x10,0x69,0x9C,0x4C, +0x26,0xEB,0x90,0x6D,0xC9,0xDE,0xE4,0x08,0xB2,0x80,0xAC,0x20,0x97,0x91,0xB7,0x90,0x0F,0x90,0x4F, +0x92,0xFB,0xC9,0xC3,0xE4,0xB7,0x14,0x3A,0xC5,0x88,0xE2,0x4C,0x09,0xA2,0x24,0x52,0xA4,0x94,0x12, +0x4A,0x35,0x65,0x3F,0xE5,0x04,0xA5,0x9F,0x32,0x42,0x99,0xA0,0xAA,0x51,0xCD,0xA9,0x9E,0xD4,0x08, +0xAA,0x88,0x3A,0x9F,0x5A,0x49,0x6D,0xA0,0x76,0x50,0x2F,0x53,0x87,0xA9,0x13,0x34,0x75,0x9A,0x25, +0xCD,0x9B,0x16,0x43,0xCB,0xA4,0x2D,0xA3,0xD5,0xD0,0x9A,0x69,0x67,0x69,0xF7,0x68,0x2F,0xE9,0x74, +0xBA,0x09,0xDD,0x83,0x1E,0x45,0x97,0xD0,0x97,0xD2,0x6B,0xE8,0x07,0xE9,0xE7,0xE9,0x83,0xF4,0x77, +0x0C,0x0D,0x86,0x0D,0x83,0xC7,0x48,0x62,0x28,0x19,0x6B,0x19,0x7B,0x19,0xA7,0x18,0xB7,0x19,0x2F, +0x99,0x4C,0xA6,0x05,0xD3,0x97,0x99,0xC8,0x54,0x30,0xD7,0x32,0x1B,0x99,0x67,0x98,0x0F,0x98,0x6F, +0x55,0x58,0x2A,0xF6,0x2A,0x7C,0x15,0x91,0xCA,0x12,0x95,0x3A,0x95,0x56,0x95,0x7E,0x95,0xE7,0xAA, +0x54,0x55,0x73,0x55,0x3F,0xD5,0x79,0xAA,0x0B,0x54,0xAB,0x55,0x0F,0xAB,0x5E,0x56,0x7D,0xA6,0x46, +0x55,0xB3,0x50,0xE3,0xA9,0x09,0xD4,0x16,0xAB,0xD5,0xA9,0x1D,0x55,0xBB,0xA9,0x36,0xAE,0xCE,0x52, +0x77,0x52,0x8F,0x50,0xCF,0x51,0x5F,0xA3,0xBE,0x5F,0xFD,0x82,0xFA,0x63,0x0D,0xB2,0x86,0x85,0x46, +0xA0,0x86,0x48,0xA3,0x54,0x63,0xB7,0xC6,0x19,0x8D,0x21,0x16,0xC6,0x32,0x65,0xF1,0x58,0x42,0xD6, +0x72,0x56,0x03,0xEB,0x2C,0x6B,0x98,0x4D,0x62,0x5B,0xB2,0xF9,0xEC,0x4C,0x76,0x05,0xFB,0x1B,0x76, +0x2F,0x7B,0x4C,0x53,0x43,0x73,0xAA,0x66,0xAC,0x66,0x91,0x66,0x9D,0xE6,0x71,0xCD,0x01,0x0E,0xC6, +0xB1,0xE0,0xF0,0x39,0xD9,0x9C,0x4A,0xCE,0x21,0xCE,0x0D,0xCE,0x7B,0x2D,0x03,0x2D,0x3F,0x2D,0xB1, +0xD6,0x6A,0xAD,0x66,0xAD,0x7E,0xAD,0x37,0xDA,0x7A,0xDA,0xBE,0xDA,0x62,0xED,0x72,0xED,0x16,0xED, +0xEB,0xDA,0xEF,0x75,0x70,0x9D,0x40,0x9D,0x2C,0x9D,0xF5,0x3A,0x6D,0x3A,0xF7,0x75,0x09,0xBA,0x36, +0xBA,0x51,0xBA,0x85,0xBA,0xDB,0x75,0xCF,0xEA,0x3E,0xD3,0x63,0xEB,0x79,0xE9,0x09,0xF5,0xCA,0xF5, +0x0E,0xE9,0xDD,0xD1,0x47,0xF5,0x6D,0xF4,0xA3,0xF5,0x17,0xEA,0xEF,0xD6,0xEF,0xD1,0x1F,0x37,0x30, +0x34,0x08,0x36,0x90,0x19,0x6C,0x31,0x38,0x63,0xF0,0xCC,0x90,0x63,0xE8,0x6B,0x98,0x69,0xB8,0xD1, +0xF0,0x84,0xE1,0xA8,0x11,0xCB,0x68,0xBA,0x91,0xC4,0x68,0xA3,0xD1,0x49,0xA3,0x27,0xB8,0x26,0xEE, +0x87,0x67,0xE3,0x35,0x78,0x17,0x3E,0x66,0xAC,0x6F,0x1C,0x62,0xAC,0x34,0xDE,0x65,0xDC,0x6B,0x3C, +0x61,0x62,0x69,0x32,0xDB,0xA4,0xC4,0xA4,0xC5,0xE4,0xBE,0x29,0xCD,0x94,0x6B,0x9A,0x66,0xBA,0xD1, +0xB4,0xD3,0x74,0xCC,0xCC,0xC8,0x2C,0xDC,0xAC,0xD8,0xAC,0xC9,0xEC,0x8E,0x39,0xD5,0x9C,0x6B,0x9E, +0x61,0xBE,0xD9,0xBC,0xDB,0xFC,0x8D,0x85,0xA5,0x45,0x9C,0xC5,0x4A,0x8B,0x36,0x8B,0xC7,0x96,0xDA, +0x96,0x7C,0xCB,0x05,0x96,0x4D,0x96,0xF7,0xAC,0x98,0x56,0x3E,0x56,0x79,0x56,0xF5,0x56,0xD7,0xAC, +0x49,0xD6,0x5C,0xEB,0x2C,0xEB,0x6D,0xD6,0x57,0x6C,0x50,0x1B,0x57,0x9B,0x0C,0x9B,0x3A,0x9B,0xCB, +0xB6,0xA8,0xAD,0x9B,0xAD,0xC4,0x76,0x9B,0x6D,0xDF,0x14,0xE2,0x14,0x8F,0x29,0xD2,0x29,0xF5,0x53, +0x6E,0xDA,0x31,0xEC,0xFC,0xEC,0x0A,0xEC,0x9A,0xEC,0x06,0xED,0x39,0xF6,0x61,0xF6,0x25,0xF6,0x6D, +0xF6,0xCF,0x1D,0xCC,0x1C,0x12,0x1D,0xD6,0x3B,0x74,0x3B,0x7C,0x72,0x74,0x75,0xCC,0x76,0x6C,0x70, +0xBC,0xEB,0xA4,0xE1,0x34,0xC3,0xA9,0xC4,0xA9,0xC3,0xE9,0x57,0x67,0x1B,0x67,0xA1,0x73,0x9D,0xF3, +0x35,0x17,0xA6,0x4B,0x90,0xCB,0x12,0x97,0x76,0x97,0x17,0x53,0x6D,0xA7,0x8A,0xA7,0x6E,0x9F,0x7A, +0xCB,0x95,0xE5,0x1A,0xEE,0xBA,0xD2,0xB5,0xD3,0xF5,0xA3,0x9B,0xBB,0x9B,0xDC,0xAD,0xD9,0x6D,0xD4, +0xDD,0xCC,0x3D,0xC5,0x7D,0xAB,0xFB,0x4D,0x2E,0x9B,0x1B,0xC9,0x5D,0xC3,0x3D,0xEF,0x41,0xF4,0xF0, +0xF7,0x58,0xE2,0x71,0xCC,0xE3,0x9D,0xA7,0x9B,0xA7,0xC2,0xF3,0x90,0xE7,0x2F,0x5E,0x76,0x5E,0x59, +0x5E,0xFB,0xBD,0x1E,0x4F,0xB3,0x9C,0x26,0x9E,0xD6,0x30,0x6D,0xC8,0xDB,0xC4,0x5B,0xE0,0xBD,0xCB, +0x7B,0x60,0x3A,0x3E,0x3D,0x65,0xFA,0xCE,0xE9,0x03,0x3E,0xC6,0x3E,0x02,0x9F,0x7A,0x9F,0x87,0xBE, +0xA6,0xBE,0x22,0xDF,0x3D,0xBE,0x23,0x7E,0xD6,0x7E,0x99,0x7E,0x07,0xFC,0x9E,0xFB,0x3B,0xFA,0xCB, +0xFD,0x8F,0xF8,0xBF,0xE1,0x79,0xF2,0x16,0xF1,0x4E,0x05,0x60,0x01,0xC1,0x01,0xE5,0x01,0xBD,0x81, +0x1A,0x81,0xB3,0x03,0x6B,0x03,0x1F,0x04,0x99,0x04,0xA5,0x07,0x35,0x05,0x8D,0x05,0xBB,0x06,0x2F, +0x0C,0x3E,0x15,0x42,0x0C,0x09,0x0D,0x59,0x1F,0x72,0x93,0x6F,0xC0,0x17,0xF2,0x1B,0xF9,0x63,0x33, +0xDC,0x67,0x2C,0x9A,0xD1,0x15,0xCA,0x08,0x9D,0x15,0x5A,0x1B,0xFA,0x30,0xCC,0x26,0x4C,0x1E,0xD6, +0x11,0x8E,0x86,0xCF,0x08,0xDF,0x10,0x7E,0x6F,0xA6,0xF9,0x4C,0xE9,0xCC,0xB6,0x08,0x88,0xE0,0x47, +0x6C,0x88,0xB8,0x1F,0x69,0x19,0x99,0x17,0xF9,0x7D,0x14,0x29,0x2A,0x32,0xAA,0x2E,0xEA,0x51,0xB4, +0x53,0x74,0x71,0x74,0xF7,0x2C,0xD6,0xAC,0xE4,0x59,0xFB,0x67,0xBD,0x8E,0xF1,0x8F,0xA9,0x8C,0xB9, +0x3B,0xDB,0x6A,0xB6,0x72,0x76,0x67,0xAC,0x6A,0x6C,0x52,0x6C,0x63,0xEC,0x9B,0xB8,0x80,0xB8,0xAA, +0xB8,0x81,0x78,0x87,0xF8,0x45,0xF1,0x97,0x12,0x74,0x13,0x24,0x09,0xED,0x89,0xE4,0xC4,0xD8,0xC4, +0x3D,0x89,0xE3,0x73,0x02,0xE7,0x6C,0x9A,0x33,0x9C,0xE4,0x9A,0x54,0x96,0x74,0x63,0xAE,0xE5,0xDC, +0xA2,0xB9,0x17,0xE6,0xE9,0xCE,0xCB,0x9E,0x77,0x3C,0x59,0x35,0x59,0x90,0x7C,0x38,0x85,0x98,0x12, +0x97,0xB2,0x3F,0xE5,0x83,0x20,0x42,0x50,0x2F,0x18,0x4F,0xE5,0xA7,0x6E,0x4D,0x1D,0x13,0xF2,0x84, +0x9B,0x85,0x4F,0x45,0xBE,0xA2,0x8D,0xA2,0x51,0xB1,0xB7,0xB8,0x4A,0x3C,0x92,0xE6,0x9D,0x56,0x95, +0xF6,0x38,0xDD,0x3B,0x7D,0x43,0xFA,0x68,0x86,0x4F,0x46,0x75,0xC6,0x33,0x09,0x4F,0x52,0x2B,0x79, +0x91,0x19,0x92,0xB9,0x23,0xF3,0x4D,0x56,0x44,0xD6,0xDE,0xAC,0xCF,0xD9,0x71,0xD9,0x2D,0x39,0x94, +0x9C,0x94,0x9C,0xA3,0x52,0x0D,0x69,0x96,0xB4,0x2B,0xD7,0x30,0xB7,0x28,0xB7,0x4F,0x66,0x2B,0x2B, +0x93,0x0D,0xE4,0x79,0xE6,0x6D,0xCA,0x1B,0x93,0x87,0xCA,0xF7,0xE4,0x23,0xF9,0x73,0xF3,0xDB,0x15, +0x6C,0x85,0x4C,0xD1,0xA3,0xB4,0x52,0xAE,0x50,0x0E,0x16,0x4C,0x2F,0xA8,0x2B,0x78,0x5B,0x18,0x5B, +0x78,0xB8,0x48,0xBD,0x48,0x5A,0xD4,0x33,0xDF,0x66,0xFE,0xEA,0xF9,0x23,0x0B,0x82,0x16,0x7C,0xBD, +0x90,0xB0,0x50,0xB8,0xB0,0xB3,0xD8,0xB8,0x78,0x59,0xF1,0xE0,0x22,0xBF,0x45,0xBB,0x16,0x23,0x8B, +0x53,0x17,0x77,0x2E,0x31,0x5D,0x52,0xBA,0x64,0x78,0x69,0xF0,0xD2,0x7D,0xCB,0x68,0xCB,0xB2,0x96, +0xFD,0x50,0xE2,0x58,0x52,0x55,0xF2,0x6A,0x79,0xDC,0xF2,0x8E,0x52,0x83,0xD2,0xA5,0xA5,0x43,0x2B, +0x82,0x57,0x34,0x95,0xA9,0x94,0xC9,0xCB,0x6E,0xAE,0xF4,0x5A,0xB9,0x63,0x15,0x61,0x95,0x64,0x55, +0xEF,0x6A,0x97,0xD5,0x5B,0x56,0x7F,0x2A,0x17,0x95,0x5F,0xAC,0x70,0xAC,0xA8,0xAE,0xF8,0xB0,0x46, +0xB8,0xE6,0xE2,0x57,0x4E,0x5F,0xD5,0x7C,0xF5,0x79,0x6D,0xDA,0xDA,0xDE,0x4A,0xB7,0xCA,0xED,0xEB, +0x48,0xEB,0xA4,0xEB,0x6E,0xAC,0xF7,0x59,0xBF,0xAF,0x4A,0xBD,0x6A,0x41,0xD5,0xD0,0x86,0xF0,0x0D, +0xAD,0x1B,0xF1,0x8D,0xE5,0x1B,0x5F,0x6D,0x4A,0xDE,0x74,0xA1,0x7A,0x6A,0xF5,0x8E,0xCD,0xB4,0xCD, +0xCA,0xCD,0x03,0x35,0x61,0x35,0xED,0x5B,0xCC,0xB6,0xAC,0xDB,0xF2,0xA1,0x36,0xA3,0xF6,0x7A,0x9D, +0x7F,0x5D,0xCB,0x56,0xFD,0xAD,0xAB,0xB7,0xBE,0xD9,0x26,0xDA,0xD6,0xBF,0xDD,0x77,0x7B,0xF3,0x0E, +0x83,0x1D,0x15,0x3B,0xDE,0xEF,0x94,0xEC,0xBC,0xB5,0x2B,0x78,0x57,0x6B,0xBD,0x45,0x7D,0xF5,0x6E, +0xD2,0xEE,0x82,0xDD,0x8F,0x1A,0x62,0x1B,0xBA,0xBF,0xE6,0x7E,0xDD,0xB8,0x47,0x77,0x4F,0xC5,0x9E, +0x8F,0x7B,0xA5,0x7B,0x07,0xF6,0x45,0xEF,0xEB,0x6A,0x74,0x6F,0x6C,0xDC,0xAF,0xBF,0xBF,0xB2,0x09, +0x6D,0x52,0x36,0x8D,0x1E,0x48,0x3A,0x70,0xE5,0x9B,0x80,0x6F,0xDA,0x9B,0xED,0x9A,0x77,0xB5,0x70, +0x5A,0x2A,0x0E,0xC2,0x41,0xE5,0xC1,0x27,0xDF,0xA6,0x7C,0x7B,0xE3,0x50,0xE8,0xA1,0xCE,0xC3,0xDC, +0xC3,0xCD,0xDF,0x99,0x7F,0xB7,0xF5,0x08,0xEB,0x48,0x79,0x2B,0xD2,0x3A,0xBF,0x75,0xAC,0x2D,0xA3, +0x6D,0xA0,0x3D,0xA1,0xBD,0xEF,0xE8,0x8C,0xA3,0x9D,0x1D,0x5E,0x1D,0x47,0xBE,0xB7,0xFF,0x7E,0xEF, +0x31,0xE3,0x63,0x75,0xC7,0x35,0x8F,0x57,0x9E,0xA0,0x9D,0x28,0x3D,0xF1,0xF9,0xE4,0x82,0x93,0xE3, +0xA7,0x64,0xA7,0x9E,0x9D,0x4E,0x3F,0x3D,0xD4,0x99,0xDC,0x79,0xF7,0x4C,0xFC,0x99,0x6B,0x5D,0x51, +0x5D,0xBD,0x67,0x43,0xCF,0x9E,0x3F,0x17,0x74,0xEE,0x4C,0xB7,0x5F,0xF7,0xC9,0xF3,0xDE,0xE7,0x8F, +0x5D,0xF0,0xBC,0x70,0xF4,0x22,0xF7,0x62,0xDB,0x25,0xB7,0x4B,0xAD,0x3D,0xAE,0x3D,0x47,0x7E,0x70, +0xFD,0xE1,0x48,0xAF,0x5B,0x6F,0xEB,0x65,0xF7,0xCB,0xED,0x57,0x3C,0xAE,0x74,0xF4,0x4D,0xEB,0x3B, +0xD1,0xEF,0xD3,0x7F,0xFA,0x6A,0xC0,0xD5,0x73,0xD7,0xF8,0xD7,0x2E,0x5D,0x9F,0x79,0xBD,0xEF,0xC6, +0xEC,0x1B,0xB7,0x6E,0x26,0xDD,0x1C,0xB8,0x25,0xBA,0xF5,0xF8,0x76,0xF6,0xED,0x17,0x77,0x0A,0xEE, +0x4C,0xDC,0x5D,0x7A,0x8F,0x78,0xAF,0xFC,0xBE,0xDA,0xFD,0xEA,0x07,0xFA,0x0F,0xEA,0x7F,0xB4,0xFE, +0xB1,0x65,0xC0,0x6D,0xE0,0xF8,0x60,0xC0,0x60,0xCF,0xC3,0x59,0x0F,0xEF,0x0E,0x09,0x87,0x9E,0xFE, +0x94,0xFF,0xD3,0x87,0xE1,0xD2,0x47,0xCC,0x47,0xD5,0x23,0x46,0x23,0x8D,0x8F,0x9D,0x1F,0x1F,0x1B, +0x0D,0x1A,0xBD,0xF2,0x64,0xCE,0x93,0xE1,0xA7,0xB2,0xA7,0x13,0xCF,0xCA,0x7E,0x56,0xFF,0x79,0xEB, +0x73,0xAB,0xE7,0xDF,0xFD,0xE2,0xFB,0x4B,0xCF,0x58,0xFC,0xD8,0xF0,0x0B,0xF9,0x8B,0xCF,0xBF,0xAE, +0x79,0xA9,0xF3,0x72,0xEF,0xAB,0xA9,0xAF,0x3A,0xC7,0x23,0xC7,0x1F,0xBC,0xCE,0x79,0x3D,0xF1,0xA6, +0xFC,0xAD,0xCE,0xDB,0x7D,0xEF,0xB8,0xEF,0xBA,0xDF,0xC7,0xBD,0x1F,0x99,0x28,0xFC,0x40,0xFE,0x50, +0xF3,0xD1,0xFA,0x63,0xC7,0xA7,0xD0,0x4F,0xF7,0x3E,0xE7,0x7C,0xFE,0xFC,0x2F,0xF7,0x84,0xF3,0xFB, +0x25,0xD2,0x9F,0x33,0x00,0x00,0x00,0x20,0x63,0x48,0x52,0x4D,0x00,0x00,0x7A,0x25,0x00,0x00,0x80, +0x83,0x00,0x00,0xF9,0xFF,0x00,0x00,0x80,0xE9,0x00,0x00,0x75,0x30,0x00,0x00,0xEA,0x60,0x00,0x00, +0x3A,0x98,0x00,0x00,0x17,0x6F,0x92,0x5F,0xC5,0x46,0x00,0x00,0x03,0x40,0x49,0x44,0x41,0x54,0x78, +0xDA,0xEC,0x5A,0xED,0x71,0xE2,0x40,0x0C,0x7D,0x64,0xEE,0x3F,0x7B,0x15,0x9C,0xAF,0x82,0x38,0x15, +0x9C,0xA9,0xE0,0xA0,0x82,0x90,0x0A,0xC2,0x55,0x00,0x54,0xC0,0xA5,0x02,0xE8,0xC0,0x50,0x81,0x49, +0x05,0x71,0x07,0xB8,0x03,0x7C,0x15,0xE8,0xFE,0x68,0x27,0x42,0xD1,0x62,0xC2,0x67,0x48,0xF6,0xCD, +0x78,0x6C,0xCB,0xFB,0xA1,0x5D,0xAD,0xA4,0xB7,0x0B,0x2D,0x22,0x42,0xC4,0xE5,0x70,0x13,0xA7,0x20, +0x1A,0x20,0x1A,0x20,0x22,0x1A,0x20,0x1A,0x20,0xE2,0x32,0xF8,0xC6,0x77,0x07,0x20,0xE5,0xE7,0x8A, +0xAF,0x6B,0x80,0xD7,0x3B,0x05,0x50,0x03,0x98,0x5D,0xAB,0x07,0xA4,0x00,0x0A,0xBE,0xEE,0xAF,0x48, +0x7F,0xAF,0xF7,0x44,0xE9,0xDD,0x07,0x30,0x60,0x03,0x5D,0x85,0x07,0x7C,0x26,0xF4,0x01,0x4C,0xF9, +0xF9,0x16,0xC0,0x43,0xCC,0x01,0xE7,0x0F,0x4B,0xD6,0x73,0xF4,0x80,0x33,0xE1,0x2F,0xDF,0xDB,0x00, +0x9E,0xBE,0x8A,0x01,0x64,0x12,0x5F,0x9E,0xA0,0xBC,0x47,0xC6,0xF7,0x92,0x93,0xAE,0x44,0x69,0x18, +0x61,0x57,0x3D,0x6A,0x55,0x7F,0x17,0x7D,0x53,0x96,0x2F,0x0F,0x9A,0x39,0x22,0x02,0x11,0x65,0xF4, +0x8A,0x21,0xCB,0x76,0xB9,0x52,0x22,0x2A,0xE8,0x2D,0xA6,0x44,0xE4,0x8C,0xF2,0x09,0x11,0xE5,0xAA, +0xEC,0x9A,0x88,0x06,0xFC,0x7D,0x25,0xEA,0xFB,0x3A,0x8E,0x88,0x26,0x46,0x1F,0xC3,0x80,0xDE,0x21, +0x59,0xC1,0x7D,0x65,0xDC,0xE6,0x54,0xB5,0xB7,0xE2,0xF1,0x40,0xF5,0x3D,0x35,0xF4,0xED,0xAA,0x71, +0x67,0xEF,0x98,0xB3,0x8D,0xEB,0x10,0x0F,0xF0,0x0C,0xC4,0x05,0x12,0x61,0x0A,0xA0,0x23,0x56,0x6A, +0x02,0xE0,0xC5,0x28,0xEF,0x98,0xC5,0xB4,0xB9,0x0C,0x14,0x0D,0x2E,0xC4,0xEA,0x93,0x18,0x35,0xAC, +0x5A,0xDD,0x87,0xF7,0x9E,0x47,0x7E,0xD6,0x7A,0x24,0x00,0x72,0x00,0x3F,0x85,0x2C,0x17,0xF5,0x64, +0x5B,0xF9,0xB1,0xA8,0xFA,0xCD,0x01,0x21,0x27,0xE7,0x7B,0xCD,0x4C,0xA3,0x05,0xE0,0x3B,0x4F,0x8C, +0x37,0xD0,0x54,0xD4,0x99,0x8A,0x41,0xCF,0x79,0xA0,0x2D,0x36,0x52,0x29,0xEA,0x49,0x0C,0xC5,0xE4, +0x97,0x5C,0xB6,0xC5,0x75,0xE7,0x01,0xC3,0x58,0x90,0xE1,0xAA,0xCB,0xEF,0x1D,0xD1,0xBF,0x5C,0x24, +0xA9,0x58,0x44,0x32,0xE4,0xDD,0x71,0xF9,0x3B,0x7E,0x4F,0x8E,0x12,0xBC,0xF7,0x0C,0x41,0x7D,0x51, +0xBE,0x6B,0x7C,0x97,0x21,0x23,0xE1,0x4B,0xBA,0xBA,0x15,0x9A,0xD6,0x86,0x4B,0xAF,0x55,0x3B,0xBA, +0xDE,0x6A,0xC7,0x10,0x04,0xD5,0xBF,0xDB,0xA2,0xAF,0xEF,0xBB,0xD8,0xD2,0x77,0xA2,0xC2,0xD2,0xDE, +0x21,0x68,0x5F,0x0F,0xF8,0x2D,0x42,0xC5,0xDC,0xF8,0xFE,0xA4,0x56,0x5C,0x57,0xBC,0x8F,0x8D,0xF2, +0x56,0x3B,0xA9,0xF0,0x98,0x59,0xC0,0xE5,0xC7,0x7B,0xE8,0x5E,0x19,0x09,0xBC,0x6E,0x48,0xF8,0x95, +0xD1,0x46,0xA9,0xDE,0xCF,0xCA,0x82,0x5C,0x43,0xC7,0x52,0xDE,0xDE,0xF2,0x6D,0x9B,0xDC,0xED,0x51, +0xE7,0x14,0xA8,0x77,0x90,0x57,0xE7,0xCE,0x01,0x4D,0x1B,0x1D,0xF7,0x01,0xEA,0x1C,0x8A,0x4A,0x78, +0x82,0xDB,0x92,0xD4,0x2F,0x92,0x84,0x17,0x22,0x4C,0x58,0x8A,0x3C,0xAA,0xB2,0xCF,0x81,0x6F,0x72, +0x40,0x7D,0x25,0x5B,0x2A,0x56,0x65,0x4D,0xF6,0x29,0xCF,0xAD,0x64,0x48,0x9C,0x88,0xFE,0x3D,0x6B, +0x3B,0xFB,0x51,0x84,0xB7,0x7A,0xC2,0x31,0xB9,0x16,0xCA,0x25,0x2A,0x76,0x0E,0xC4,0x24,0x96,0x7C, +0xAF,0x8C,0xEF,0x72,0x40,0x72,0x82,0x7F,0x89,0xD8,0xAF,0x59,0x97,0xC7,0x40,0xE5,0x96,0x63,0x63, +0x2C,0xC6,0xD8,0x07,0xB0,0x62,0x4A,0xBC,0x32,0x16,0x8B,0x64,0x7A,0x64,0xB0,0x3F,0x2D,0xDB,0xCA, +0x82,0x9A,0x30,0x34,0x98,0x10,0x31,0x6B,0x78,0x51,0x1B,0x96,0x54,0x6D,0xDA,0xF4,0xC6,0xA7,0x10, +0x4C,0x67,0x6D,0xF4,0xE1,0x94,0x7C,0xCD,0x75,0x56,0xA2,0x0D,0x52,0x9B,0xB7,0x26,0x16,0x54,0x18, +0x6C,0x64,0x18,0x60,0x34,0xA9,0xEA,0xC3,0x23,0x57,0x63,0xB5,0xE6,0x30,0x0B,0xC8,0x0E,0x66,0x41, +0xFF,0xC4,0xEA,0x7C,0x10,0xAB,0x24,0xC3,0xE6,0x6F,0x0A,0x1D,0xC5,0x14,0x4A,0x83,0x73,0xFB,0xF8, +0x3A,0x02,0xD0,0x0B,0x24,0x3A,0xD9,0x8E,0xF6,0xC2,0x3F,0x6A,0x23,0x75,0x6C,0x94,0xBC,0xE7,0xE8, +0xB1,0x8E,0x23,0xDE,0x07,0xF4,0x8C,0x5C,0x21,0xD9,0x55,0x8D,0xD7,0xDF,0x55,0xB4,0x6C,0x03,0x2D, +0xFE,0x5B,0x8A,0xDB,0x71,0x53,0x93,0x70,0x6C,0xAC,0x8D,0xD0,0x74,0xCB,0xEF,0xCF,0x0D,0xE7,0x23, +0x8E,0x43,0xC7,0x0F,0x36,0xE6,0x5C,0x85,0xA7,0x2A,0xC0,0x2A,0xBA,0xA2,0x8F,0x85,0x30,0x4A,0x26, +0x06,0x58,0x22,0xFC,0xE3,0x92,0x2E,0xA7,0xC7,0x95,0x18,0xE7,0x4C,0x43,0x96,0x2F,0x78,0x4C,0x35, +0xBF,0xDF,0x8B,0x8D,0xE3,0x4C,0x1C,0x79,0xA7,0x4C,0xD1,0xA5,0x7E,0x96,0xEC,0x8D,0x01,0x22,0x6C, +0xE4,0x0D,0x79,0xA6,0x66,0x8F,0xB8,0x18,0x0D,0xFD,0xEC,0x18,0x07,0x36,0x9A,0x9E,0x60,0x74,0x0E, +0xDD,0x8B,0x44,0x0F,0x78,0xFF,0x51,0x78,0xE8,0x38,0x3C,0x1A,0xE0,0x1A,0x11,0x43,0x50,0x34,0x40, +0x34,0x40,0x44,0x34,0xC0,0xD7,0xC5,0xFF,0x01,0x00,0xCC,0x01,0x97,0x8B,0x00,0x58,0xE9,0x5F,0x00, +0x00,0x00,0x00,0x49,0x45,0x4E,0x44,0xAE,0x42,0x60,0x82}; +unsigned char LoadCircle[]= +{0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x30, +0x00,0x00,0x00,0x2E,0x08,0x06,0x00,0x00,0x00,0x6E,0xDE,0x9A,0x6C,0x00,0x00,0x00,0x09,0x70,0x48, +0x59,0x73,0x00,0x00,0x0B,0x13,0x00,0x00,0x0B,0x13,0x01,0x00,0x9A,0x9C,0x18,0x00,0x00,0x0A,0x4D, +0x69,0x43,0x43,0x50,0x50,0x68,0x6F,0x74,0x6F,0x73,0x68,0x6F,0x70,0x20,0x49,0x43,0x43,0x20,0x70, +0x72,0x6F,0x66,0x69,0x6C,0x65,0x00,0x00,0x78,0xDA,0x9D,0x53,0x77,0x58,0x93,0xF7,0x16,0x3E,0xDF, +0xF7,0x65,0x0F,0x56,0x42,0xD8,0xF0,0xB1,0x97,0x6C,0x81,0x00,0x22,0x23,0xAC,0x08,0xC8,0x10,0x59, +0xA2,0x10,0x92,0x00,0x61,0x84,0x10,0x12,0x40,0xC5,0x85,0x88,0x0A,0x56,0x14,0x15,0x11,0x9C,0x48, +0x55,0xC4,0x82,0xD5,0x0A,0x48,0x9D,0x88,0xE2,0xA0,0x28,0xB8,0x67,0x41,0x8A,0x88,0x5A,0x8B,0x55, +0x5C,0x38,0xEE,0x1F,0xDC,0xA7,0xB5,0x7D,0x7A,0xEF,0xED,0xED,0xFB,0xD7,0xFB,0xBC,0xE7,0x9C,0xE7, +0xFC,0xCE,0x79,0xCF,0x0F,0x80,0x11,0x12,0x26,0x91,0xE6,0xA2,0x6A,0x00,0x39,0x52,0x85,0x3C,0x3A, +0xD8,0x1F,0x8F,0x4F,0x48,0xC4,0xC9,0xBD,0x80,0x02,0x15,0x48,0xE0,0x04,0x20,0x10,0xE6,0xCB,0xC2, +0x67,0x05,0xC5,0x00,0x00,0xF0,0x03,0x79,0x78,0x7E,0x74,0xB0,0x3F,0xFC,0x01,0xAF,0x6F,0x00,0x02, +0x00,0x70,0xD5,0x2E,0x24,0x12,0xC7,0xE1,0xFF,0x83,0xBA,0x50,0x26,0x57,0x00,0x20,0x91,0x00,0xE0, +0x22,0x12,0xE7,0x0B,0x01,0x90,0x52,0x00,0xC8,0x2E,0x54,0xC8,0x14,0x00,0xC8,0x18,0x00,0xB0,0x53, +0xB3,0x64,0x0A,0x00,0x94,0x00,0x00,0x6C,0x79,0x7C,0x42,0x22,0x00,0xAA,0x0D,0x00,0xEC,0xF4,0x49, +0x3E,0x05,0x00,0xD8,0xA9,0x93,0xDC,0x17,0x00,0xD8,0xA2,0x1C,0xA9,0x08,0x00,0x8D,0x01,0x00,0x99, +0x28,0x47,0x24,0x02,0x40,0xBB,0x00,0x60,0x55,0x81,0x52,0x2C,0x02,0xC0,0xC2,0x00,0xA0,0xAC,0x40, +0x22,0x2E,0x04,0xC0,0xAE,0x01,0x80,0x59,0xB6,0x32,0x47,0x02,0x80,0xBD,0x05,0x00,0x76,0x8E,0x58, +0x90,0x0F,0x40,0x60,0x00,0x80,0x99,0x42,0x2C,0xCC,0x00,0x20,0x38,0x02,0x00,0x43,0x1E,0x13,0xCD, +0x03,0x20,0x4C,0x03,0xA0,0x30,0xD2,0xBF,0xE0,0xA9,0x5F,0x70,0x85,0xB8,0x48,0x01,0x00,0xC0,0xCB, +0x95,0xCD,0x97,0x4B,0xD2,0x33,0x14,0xB8,0x95,0xD0,0x1A,0x77,0xF2,0xF0,0xE0,0xE2,0x21,0xE2,0xC2, +0x6C,0xB1,0x42,0x61,0x17,0x29,0x10,0x66,0x09,0xE4,0x22,0x9C,0x97,0x9B,0x23,0x13,0x48,0xE7,0x03, +0x4C,0xCE,0x0C,0x00,0x00,0x1A,0xF9,0xD1,0xC1,0xFE,0x38,0x3F,0x90,0xE7,0xE6,0xE4,0xE1,0xE6,0x66, +0xE7,0x6C,0xEF,0xF4,0xC5,0xA2,0xFE,0x6B,0xF0,0x6F,0x22,0x3E,0x21,0xF1,0xDF,0xFE,0xBC,0x8C,0x02, +0x04,0x00,0x10,0x4E,0xCF,0xEF,0xDA,0x5F,0xE5,0xE5,0xD6,0x03,0x70,0xC7,0x01,0xB0,0x75,0xBF,0x6B, +0xA9,0x5B,0x00,0xDA,0x56,0x00,0x68,0xDF,0xF9,0x5D,0x33,0xDB,0x09,0xA0,0x5A,0x0A,0xD0,0x7A,0xF9, +0x8B,0x79,0x38,0xFC,0x40,0x1E,0x9E,0xA1,0x50,0xC8,0x3C,0x1D,0x1C,0x0A,0x0B,0x0B,0xED,0x25,0x62, +0xA1,0xBD,0x30,0xE3,0x8B,0x3E,0xFF,0x33,0xE1,0x6F,0xE0,0x8B,0x7E,0xF6,0xFC,0x40,0x1E,0xFE,0xDB, +0x7A,0xF0,0x00,0x71,0x9A,0x40,0x99,0xAD,0xC0,0xA3,0x83,0xFD,0x71,0x61,0x6E,0x76,0xAE,0x52,0x8E, +0xE7,0xCB,0x04,0x42,0x31,0x6E,0xF7,0xE7,0x23,0xFE,0xC7,0x85,0x7F,0xFD,0x8E,0x29,0xD1,0xE2,0x34, +0xB1,0x5C,0x2C,0x15,0x8A,0xF1,0x58,0x89,0xB8,0x50,0x22,0x4D,0xC7,0x79,0xB9,0x52,0x91,0x44,0x21, +0xC9,0x95,0xE2,0x12,0xE9,0x7F,0x32,0xF1,0x1F,0x96,0xFD,0x09,0x93,0x77,0x0D,0x00,0xAC,0x86,0x4F, +0xC0,0x4E,0xB6,0x07,0xB5,0xCB,0x6C,0xC0,0x7E,0xEE,0x01,0x02,0x8B,0x0E,0x58,0xD2,0x76,0x00,0x40, +0x7E,0xF3,0x2D,0x8C,0x1A,0x0B,0x91,0x00,0x10,0x67,0x34,0x32,0x79,0xF7,0x00,0x00,0x93,0xBF,0xF9, +0x8F,0x40,0x2B,0x01,0x00,0xCD,0x97,0xA4,0xE3,0x00,0x00,0xBC,0xE8,0x18,0x5C,0xA8,0x94,0x17,0x4C, +0xC6,0x08,0x00,0x00,0x44,0xA0,0x81,0x2A,0xB0,0x41,0x07,0x0C,0xC1,0x14,0xAC,0xC0,0x0E,0x9C,0xC1, +0x1D,0xBC,0xC0,0x17,0x02,0x61,0x06,0x44,0x40,0x0C,0x24,0xC0,0x3C,0x10,0x42,0x06,0xE4,0x80,0x1C, +0x0A,0xA1,0x18,0x96,0x41,0x19,0x54,0xC0,0x3A,0xD8,0x04,0xB5,0xB0,0x03,0x1A,0xA0,0x11,0x9A,0xE1, +0x10,0xB4,0xC1,0x31,0x38,0x0D,0xE7,0xE0,0x12,0x5C,0x81,0xEB,0x70,0x17,0x06,0x60,0x18,0x9E,0xC2, +0x18,0xBC,0x86,0x09,0x04,0x41,0xC8,0x08,0x13,0x61,0x21,0x3A,0x88,0x11,0x62,0x8E,0xD8,0x22,0xCE, +0x08,0x17,0x99,0x8E,0x04,0x22,0x61,0x48,0x34,0x92,0x80,0xA4,0x20,0xE9,0x88,0x14,0x51,0x22,0xC5, +0xC8,0x72,0xA4,0x02,0xA9,0x42,0x6A,0x91,0x5D,0x48,0x23,0xF2,0x2D,0x72,0x14,0x39,0x8D,0x5C,0x40, +0xFA,0x90,0xDB,0xC8,0x20,0x32,0x8A,0xFC,0x8A,0xBC,0x47,0x31,0x94,0x81,0xB2,0x51,0x03,0xD4,0x02, +0x75,0x40,0xB9,0xA8,0x1F,0x1A,0x8A,0xC6,0xA0,0x73,0xD1,0x74,0x34,0x0F,0x5D,0x80,0x96,0xA2,0x6B, +0xD1,0x1A,0xB4,0x1E,0x3D,0x80,0xB6,0xA2,0xA7,0xD1,0x4B,0xE8,0x75,0x74,0x00,0x7D,0x8A,0x8E,0x63, +0x80,0xD1,0x31,0x0E,0x66,0x8C,0xD9,0x61,0x5C,0x8C,0x87,0x45,0x60,0x89,0x58,0x1A,0x26,0xC7,0x16, +0x63,0xE5,0x58,0x35,0x56,0x8F,0x35,0x63,0x1D,0x58,0x37,0x76,0x15,0x1B,0xC0,0x9E,0x61,0xEF,0x08, +0x24,0x02,0x8B,0x80,0x13,0xEC,0x08,0x5E,0x84,0x10,0xC2,0x6C,0x82,0x90,0x90,0x47,0x58,0x4C,0x58, +0x43,0xA8,0x25,0xEC,0x23,0xB4,0x12,0xBA,0x08,0x57,0x09,0x83,0x84,0x31,0xC2,0x27,0x22,0x93,0xA8, +0x4F,0xB4,0x25,0x7A,0x12,0xF9,0xC4,0x78,0x62,0x3A,0xB1,0x90,0x58,0x46,0xAC,0x26,0xEE,0x21,0x1E, +0x21,0x9E,0x25,0x5E,0x27,0x0E,0x13,0x5F,0x93,0x48,0x24,0x0E,0xC9,0x92,0xE4,0x4E,0x0A,0x21,0x25, +0x90,0x32,0x49,0x0B,0x49,0x6B,0x48,0xDB,0x48,0x2D,0xA4,0x53,0xA4,0x3E,0xD2,0x10,0x69,0x9C,0x4C, +0x26,0xEB,0x90,0x6D,0xC9,0xDE,0xE4,0x08,0xB2,0x80,0xAC,0x20,0x97,0x91,0xB7,0x90,0x0F,0x90,0x4F, +0x92,0xFB,0xC9,0xC3,0xE4,0xB7,0x14,0x3A,0xC5,0x88,0xE2,0x4C,0x09,0xA2,0x24,0x52,0xA4,0x94,0x12, +0x4A,0x35,0x65,0x3F,0xE5,0x04,0xA5,0x9F,0x32,0x42,0x99,0xA0,0xAA,0x51,0xCD,0xA9,0x9E,0xD4,0x08, +0xAA,0x88,0x3A,0x9F,0x5A,0x49,0x6D,0xA0,0x76,0x50,0x2F,0x53,0x87,0xA9,0x13,0x34,0x75,0x9A,0x25, +0xCD,0x9B,0x16,0x43,0xCB,0xA4,0x2D,0xA3,0xD5,0xD0,0x9A,0x69,0x67,0x69,0xF7,0x68,0x2F,0xE9,0x74, +0xBA,0x09,0xDD,0x83,0x1E,0x45,0x97,0xD0,0x97,0xD2,0x6B,0xE8,0x07,0xE9,0xE7,0xE9,0x83,0xF4,0x77, +0x0C,0x0D,0x86,0x0D,0x83,0xC7,0x48,0x62,0x28,0x19,0x6B,0x19,0x7B,0x19,0xA7,0x18,0xB7,0x19,0x2F, +0x99,0x4C,0xA6,0x05,0xD3,0x97,0x99,0xC8,0x54,0x30,0xD7,0x32,0x1B,0x99,0x67,0x98,0x0F,0x98,0x6F, +0x55,0x58,0x2A,0xF6,0x2A,0x7C,0x15,0x91,0xCA,0x12,0x95,0x3A,0x95,0x56,0x95,0x7E,0x95,0xE7,0xAA, +0x54,0x55,0x73,0x55,0x3F,0xD5,0x79,0xAA,0x0B,0x54,0xAB,0x55,0x0F,0xAB,0x5E,0x56,0x7D,0xA6,0x46, +0x55,0xB3,0x50,0xE3,0xA9,0x09,0xD4,0x16,0xAB,0xD5,0xA9,0x1D,0x55,0xBB,0xA9,0x36,0xAE,0xCE,0x52, +0x77,0x52,0x8F,0x50,0xCF,0x51,0x5F,0xA3,0xBE,0x5F,0xFD,0x82,0xFA,0x63,0x0D,0xB2,0x86,0x85,0x46, +0xA0,0x86,0x48,0xA3,0x54,0x63,0xB7,0xC6,0x19,0x8D,0x21,0x16,0xC6,0x32,0x65,0xF1,0x58,0x42,0xD6, +0x72,0x56,0x03,0xEB,0x2C,0x6B,0x98,0x4D,0x62,0x5B,0xB2,0xF9,0xEC,0x4C,0x76,0x05,0xFB,0x1B,0x76, +0x2F,0x7B,0x4C,0x53,0x43,0x73,0xAA,0x66,0xAC,0x66,0x91,0x66,0x9D,0xE6,0x71,0xCD,0x01,0x0E,0xC6, +0xB1,0xE0,0xF0,0x39,0xD9,0x9C,0x4A,0xCE,0x21,0xCE,0x0D,0xCE,0x7B,0x2D,0x03,0x2D,0x3F,0x2D,0xB1, +0xD6,0x6A,0xAD,0x66,0xAD,0x7E,0xAD,0x37,0xDA,0x7A,0xDA,0xBE,0xDA,0x62,0xED,0x72,0xED,0x16,0xED, +0xEB,0xDA,0xEF,0x75,0x70,0x9D,0x40,0x9D,0x2C,0x9D,0xF5,0x3A,0x6D,0x3A,0xF7,0x75,0x09,0xBA,0x36, +0xBA,0x51,0xBA,0x85,0xBA,0xDB,0x75,0xCF,0xEA,0x3E,0xD3,0x63,0xEB,0x79,0xE9,0x09,0xF5,0xCA,0xF5, +0x0E,0xE9,0xDD,0xD1,0x47,0xF5,0x6D,0xF4,0xA3,0xF5,0x17,0xEA,0xEF,0xD6,0xEF,0xD1,0x1F,0x37,0x30, +0x34,0x08,0x36,0x90,0x19,0x6C,0x31,0x38,0x63,0xF0,0xCC,0x90,0x63,0xE8,0x6B,0x98,0x69,0xB8,0xD1, +0xF0,0x84,0xE1,0xA8,0x11,0xCB,0x68,0xBA,0x91,0xC4,0x68,0xA3,0xD1,0x49,0xA3,0x27,0xB8,0x26,0xEE, +0x87,0x67,0xE3,0x35,0x78,0x17,0x3E,0x66,0xAC,0x6F,0x1C,0x62,0xAC,0x34,0xDE,0x65,0xDC,0x6B,0x3C, +0x61,0x62,0x69,0x32,0xDB,0xA4,0xC4,0xA4,0xC5,0xE4,0xBE,0x29,0xCD,0x94,0x6B,0x9A,0x66,0xBA,0xD1, +0xB4,0xD3,0x74,0xCC,0xCC,0xC8,0x2C,0xDC,0xAC,0xD8,0xAC,0xC9,0xEC,0x8E,0x39,0xD5,0x9C,0x6B,0x9E, +0x61,0xBE,0xD9,0xBC,0xDB,0xFC,0x8D,0x85,0xA5,0x45,0x9C,0xC5,0x4A,0x8B,0x36,0x8B,0xC7,0x96,0xDA, +0x96,0x7C,0xCB,0x05,0x96,0x4D,0x96,0xF7,0xAC,0x98,0x56,0x3E,0x56,0x79,0x56,0xF5,0x56,0xD7,0xAC, +0x49,0xD6,0x5C,0xEB,0x2C,0xEB,0x6D,0xD6,0x57,0x6C,0x50,0x1B,0x57,0x9B,0x0C,0x9B,0x3A,0x9B,0xCB, +0xB6,0xA8,0xAD,0x9B,0xAD,0xC4,0x76,0x9B,0x6D,0xDF,0x14,0xE2,0x14,0x8F,0x29,0xD2,0x29,0xF5,0x53, +0x6E,0xDA,0x31,0xEC,0xFC,0xEC,0x0A,0xEC,0x9A,0xEC,0x06,0xED,0x39,0xF6,0x61,0xF6,0x25,0xF6,0x6D, +0xF6,0xCF,0x1D,0xCC,0x1C,0x12,0x1D,0xD6,0x3B,0x74,0x3B,0x7C,0x72,0x74,0x75,0xCC,0x76,0x6C,0x70, +0xBC,0xEB,0xA4,0xE1,0x34,0xC3,0xA9,0xC4,0xA9,0xC3,0xE9,0x57,0x67,0x1B,0x67,0xA1,0x73,0x9D,0xF3, +0x35,0x17,0xA6,0x4B,0x90,0xCB,0x12,0x97,0x76,0x97,0x17,0x53,0x6D,0xA7,0x8A,0xA7,0x6E,0x9F,0x7A, +0xCB,0x95,0xE5,0x1A,0xEE,0xBA,0xD2,0xB5,0xD3,0xF5,0xA3,0x9B,0xBB,0x9B,0xDC,0xAD,0xD9,0x6D,0xD4, +0xDD,0xCC,0x3D,0xC5,0x7D,0xAB,0xFB,0x4D,0x2E,0x9B,0x1B,0xC9,0x5D,0xC3,0x3D,0xEF,0x41,0xF4,0xF0, +0xF7,0x58,0xE2,0x71,0xCC,0xE3,0x9D,0xA7,0x9B,0xA7,0xC2,0xF3,0x90,0xE7,0x2F,0x5E,0x76,0x5E,0x59, +0x5E,0xFB,0xBD,0x1E,0x4F,0xB3,0x9C,0x26,0x9E,0xD6,0x30,0x6D,0xC8,0xDB,0xC4,0x5B,0xE0,0xBD,0xCB, +0x7B,0x60,0x3A,0x3E,0x3D,0x65,0xFA,0xCE,0xE9,0x03,0x3E,0xC6,0x3E,0x02,0x9F,0x7A,0x9F,0x87,0xBE, +0xA6,0xBE,0x22,0xDF,0x3D,0xBE,0x23,0x7E,0xD6,0x7E,0x99,0x7E,0x07,0xFC,0x9E,0xFB,0x3B,0xFA,0xCB, +0xFD,0x8F,0xF8,0xBF,0xE1,0x79,0xF2,0x16,0xF1,0x4E,0x05,0x60,0x01,0xC1,0x01,0xE5,0x01,0xBD,0x81, +0x1A,0x81,0xB3,0x03,0x6B,0x03,0x1F,0x04,0x99,0x04,0xA5,0x07,0x35,0x05,0x8D,0x05,0xBB,0x06,0x2F, +0x0C,0x3E,0x15,0x42,0x0C,0x09,0x0D,0x59,0x1F,0x72,0x93,0x6F,0xC0,0x17,0xF2,0x1B,0xF9,0x63,0x33, +0xDC,0x67,0x2C,0x9A,0xD1,0x15,0xCA,0x08,0x9D,0x15,0x5A,0x1B,0xFA,0x30,0xCC,0x26,0x4C,0x1E,0xD6, +0x11,0x8E,0x86,0xCF,0x08,0xDF,0x10,0x7E,0x6F,0xA6,0xF9,0x4C,0xE9,0xCC,0xB6,0x08,0x88,0xE0,0x47, +0x6C,0x88,0xB8,0x1F,0x69,0x19,0x99,0x17,0xF9,0x7D,0x14,0x29,0x2A,0x32,0xAA,0x2E,0xEA,0x51,0xB4, +0x53,0x74,0x71,0x74,0xF7,0x2C,0xD6,0xAC,0xE4,0x59,0xFB,0x67,0xBD,0x8E,0xF1,0x8F,0xA9,0x8C,0xB9, +0x3B,0xDB,0x6A,0xB6,0x72,0x76,0x67,0xAC,0x6A,0x6C,0x52,0x6C,0x63,0xEC,0x9B,0xB8,0x80,0xB8,0xAA, +0xB8,0x81,0x78,0x87,0xF8,0x45,0xF1,0x97,0x12,0x74,0x13,0x24,0x09,0xED,0x89,0xE4,0xC4,0xD8,0xC4, +0x3D,0x89,0xE3,0x73,0x02,0xE7,0x6C,0x9A,0x33,0x9C,0xE4,0x9A,0x54,0x96,0x74,0x63,0xAE,0xE5,0xDC, +0xA2,0xB9,0x17,0xE6,0xE9,0xCE,0xCB,0x9E,0x77,0x3C,0x59,0x35,0x59,0x90,0x7C,0x38,0x85,0x98,0x12, +0x97,0xB2,0x3F,0xE5,0x83,0x20,0x42,0x50,0x2F,0x18,0x4F,0xE5,0xA7,0x6E,0x4D,0x1D,0x13,0xF2,0x84, +0x9B,0x85,0x4F,0x45,0xBE,0xA2,0x8D,0xA2,0x51,0xB1,0xB7,0xB8,0x4A,0x3C,0x92,0xE6,0x9D,0x56,0x95, +0xF6,0x38,0xDD,0x3B,0x7D,0x43,0xFA,0x68,0x86,0x4F,0x46,0x75,0xC6,0x33,0x09,0x4F,0x52,0x2B,0x79, +0x91,0x19,0x92,0xB9,0x23,0xF3,0x4D,0x56,0x44,0xD6,0xDE,0xAC,0xCF,0xD9,0x71,0xD9,0x2D,0x39,0x94, +0x9C,0x94,0x9C,0xA3,0x52,0x0D,0x69,0x96,0xB4,0x2B,0xD7,0x30,0xB7,0x28,0xB7,0x4F,0x66,0x2B,0x2B, +0x93,0x0D,0xE4,0x79,0xE6,0x6D,0xCA,0x1B,0x93,0x87,0xCA,0xF7,0xE4,0x23,0xF9,0x73,0xF3,0xDB,0x15, +0x6C,0x85,0x4C,0xD1,0xA3,0xB4,0x52,0xAE,0x50,0x0E,0x16,0x4C,0x2F,0xA8,0x2B,0x78,0x5B,0x18,0x5B, +0x78,0xB8,0x48,0xBD,0x48,0x5A,0xD4,0x33,0xDF,0x66,0xFE,0xEA,0xF9,0x23,0x0B,0x82,0x16,0x7C,0xBD, +0x90,0xB0,0x50,0xB8,0xB0,0xB3,0xD8,0xB8,0x78,0x59,0xF1,0xE0,0x22,0xBF,0x45,0xBB,0x16,0x23,0x8B, +0x53,0x17,0x77,0x2E,0x31,0x5D,0x52,0xBA,0x64,0x78,0x69,0xF0,0xD2,0x7D,0xCB,0x68,0xCB,0xB2,0x96, +0xFD,0x50,0xE2,0x58,0x52,0x55,0xF2,0x6A,0x79,0xDC,0xF2,0x8E,0x52,0x83,0xD2,0xA5,0xA5,0x43,0x2B, +0x82,0x57,0x34,0x95,0xA9,0x94,0xC9,0xCB,0x6E,0xAE,0xF4,0x5A,0xB9,0x63,0x15,0x61,0x95,0x64,0x55, +0xEF,0x6A,0x97,0xD5,0x5B,0x56,0x7F,0x2A,0x17,0x95,0x5F,0xAC,0x70,0xAC,0xA8,0xAE,0xF8,0xB0,0x46, +0xB8,0xE6,0xE2,0x57,0x4E,0x5F,0xD5,0x7C,0xF5,0x79,0x6D,0xDA,0xDA,0xDE,0x4A,0xB7,0xCA,0xED,0xEB, +0x48,0xEB,0xA4,0xEB,0x6E,0xAC,0xF7,0x59,0xBF,0xAF,0x4A,0xBD,0x6A,0x41,0xD5,0xD0,0x86,0xF0,0x0D, +0xAD,0x1B,0xF1,0x8D,0xE5,0x1B,0x5F,0x6D,0x4A,0xDE,0x74,0xA1,0x7A,0x6A,0xF5,0x8E,0xCD,0xB4,0xCD, +0xCA,0xCD,0x03,0x35,0x61,0x35,0xED,0x5B,0xCC,0xB6,0xAC,0xDB,0xF2,0xA1,0x36,0xA3,0xF6,0x7A,0x9D, +0x7F,0x5D,0xCB,0x56,0xFD,0xAD,0xAB,0xB7,0xBE,0xD9,0x26,0xDA,0xD6,0xBF,0xDD,0x77,0x7B,0xF3,0x0E, +0x83,0x1D,0x15,0x3B,0xDE,0xEF,0x94,0xEC,0xBC,0xB5,0x2B,0x78,0x57,0x6B,0xBD,0x45,0x7D,0xF5,0x6E, +0xD2,0xEE,0x82,0xDD,0x8F,0x1A,0x62,0x1B,0xBA,0xBF,0xE6,0x7E,0xDD,0xB8,0x47,0x77,0x4F,0xC5,0x9E, +0x8F,0x7B,0xA5,0x7B,0x07,0xF6,0x45,0xEF,0xEB,0x6A,0x74,0x6F,0x6C,0xDC,0xAF,0xBF,0xBF,0xB2,0x09, +0x6D,0x52,0x36,0x8D,0x1E,0x48,0x3A,0x70,0xE5,0x9B,0x80,0x6F,0xDA,0x9B,0xED,0x9A,0x77,0xB5,0x70, +0x5A,0x2A,0x0E,0xC2,0x41,0xE5,0xC1,0x27,0xDF,0xA6,0x7C,0x7B,0xE3,0x50,0xE8,0xA1,0xCE,0xC3,0xDC, +0xC3,0xCD,0xDF,0x99,0x7F,0xB7,0xF5,0x08,0xEB,0x48,0x79,0x2B,0xD2,0x3A,0xBF,0x75,0xAC,0x2D,0xA3, +0x6D,0xA0,0x3D,0xA1,0xBD,0xEF,0xE8,0x8C,0xA3,0x9D,0x1D,0x5E,0x1D,0x47,0xBE,0xB7,0xFF,0x7E,0xEF, +0x31,0xE3,0x63,0x75,0xC7,0x35,0x8F,0x57,0x9E,0xA0,0x9D,0x28,0x3D,0xF1,0xF9,0xE4,0x82,0x93,0xE3, +0xA7,0x64,0xA7,0x9E,0x9D,0x4E,0x3F,0x3D,0xD4,0x99,0xDC,0x79,0xF7,0x4C,0xFC,0x99,0x6B,0x5D,0x51, +0x5D,0xBD,0x67,0x43,0xCF,0x9E,0x3F,0x17,0x74,0xEE,0x4C,0xB7,0x5F,0xF7,0xC9,0xF3,0xDE,0xE7,0x8F, +0x5D,0xF0,0xBC,0x70,0xF4,0x22,0xF7,0x62,0xDB,0x25,0xB7,0x4B,0xAD,0x3D,0xAE,0x3D,0x47,0x7E,0x70, +0xFD,0xE1,0x48,0xAF,0x5B,0x6F,0xEB,0x65,0xF7,0xCB,0xED,0x57,0x3C,0xAE,0x74,0xF4,0x4D,0xEB,0x3B, +0xD1,0xEF,0xD3,0x7F,0xFA,0x6A,0xC0,0xD5,0x73,0xD7,0xF8,0xD7,0x2E,0x5D,0x9F,0x79,0xBD,0xEF,0xC6, +0xEC,0x1B,0xB7,0x6E,0x26,0xDD,0x1C,0xB8,0x25,0xBA,0xF5,0xF8,0x76,0xF6,0xED,0x17,0x77,0x0A,0xEE, +0x4C,0xDC,0x5D,0x7A,0x8F,0x78,0xAF,0xFC,0xBE,0xDA,0xFD,0xEA,0x07,0xFA,0x0F,0xEA,0x7F,0xB4,0xFE, +0xB1,0x65,0xC0,0x6D,0xE0,0xF8,0x60,0xC0,0x60,0xCF,0xC3,0x59,0x0F,0xEF,0x0E,0x09,0x87,0x9E,0xFE, +0x94,0xFF,0xD3,0x87,0xE1,0xD2,0x47,0xCC,0x47,0xD5,0x23,0x46,0x23,0x8D,0x8F,0x9D,0x1F,0x1F,0x1B, +0x0D,0x1A,0xBD,0xF2,0x64,0xCE,0x93,0xE1,0xA7,0xB2,0xA7,0x13,0xCF,0xCA,0x7E,0x56,0xFF,0x79,0xEB, +0x73,0xAB,0xE7,0xDF,0xFD,0xE2,0xFB,0x4B,0xCF,0x58,0xFC,0xD8,0xF0,0x0B,0xF9,0x8B,0xCF,0xBF,0xAE, +0x79,0xA9,0xF3,0x72,0xEF,0xAB,0xA9,0xAF,0x3A,0xC7,0x23,0xC7,0x1F,0xBC,0xCE,0x79,0x3D,0xF1,0xA6, +0xFC,0xAD,0xCE,0xDB,0x7D,0xEF,0xB8,0xEF,0xBA,0xDF,0xC7,0xBD,0x1F,0x99,0x28,0xFC,0x40,0xFE,0x50, +0xF3,0xD1,0xFA,0x63,0xC7,0xA7,0xD0,0x4F,0xF7,0x3E,0xE7,0x7C,0xFE,0xFC,0x2F,0xF7,0x84,0xF3,0xFB, +0x25,0xD2,0x9F,0x33,0x00,0x00,0x00,0x20,0x63,0x48,0x52,0x4D,0x00,0x00,0x7A,0x25,0x00,0x00,0x80, +0x83,0x00,0x00,0xF9,0xFF,0x00,0x00,0x80,0xE9,0x00,0x00,0x75,0x30,0x00,0x00,0xEA,0x60,0x00,0x00, +0x3A,0x98,0x00,0x00,0x17,0x6F,0x92,0x5F,0xC5,0x46,0x00,0x00,0x03,0x6A,0x49,0x44,0x41,0x54,0x78, +0xDA,0xD4,0x99,0xDB,0x8B,0x4D,0x51,0x1C,0xC7,0x3F,0x73,0x30,0x33,0xB9,0x1B,0x91,0x26,0xE4,0x96, +0x41,0x23,0x64,0xBC,0x10,0x21,0x22,0x49,0xE4,0xC1,0x03,0x25,0xA6,0x49,0xE3,0x6F,0xF0,0xE4,0x4D, +0xA3,0x88,0x72,0x8B,0x79,0x91,0x86,0x22,0x21,0x91,0x68,0x94,0x6B,0x6E,0x33,0xEE,0x23,0x14,0x66, +0x18,0x53,0x43,0x72,0x3B,0xE3,0xFA,0xF5,0x60,0x4D,0x9D,0x8E,0x73,0xF6,0x59,0x6B,0xED,0x7D,0xCE, +0x71,0xBE,0xB5,0xDA,0x9D,0xCE,0xDA,0xBF,0xB5,0xBE,0xEB,0xB7,0x7E,0xD7,0x5D,0x24,0x89,0x42,0x46, +0xCF,0x88,0xE4,0x14,0x03,0x53,0x81,0xF1,0x40,0x15,0x30,0x0E,0x18,0x06,0xF4,0x06,0x3E,0x03,0xED, +0xC0,0x33,0xE0,0x16,0xF0,0x04,0x68,0x02,0xF4,0x3F,0x10,0x98,0x02,0xD4,0x00,0xCB,0x80,0x11,0x0E, +0xEF,0x3D,0x07,0x4E,0x00,0x07,0x80,0x47,0xA1,0x76,0x20,0xC9,0x67,0xCC,0x94,0x74,0x51,0xD1,0xE0, +0xB4,0xA4,0xE9,0x9E,0xFB,0x70,0x26,0x50,0x26,0xE9,0xB0,0xB2,0x83,0x7A,0x49,0xFD,0x5D,0x09,0x14, +0x39,0x18,0xF1,0x2C,0xA3,0xF6,0xC1,0x59,0xB4,0xC9,0x37,0xC0,0x12,0xE0,0xAE,0xED,0x0B,0x31,0xCB, +0x79,0x6B,0x81,0xCB,0x59,0xDE,0x3C,0x40,0x39,0x70,0x07,0x58,0x1E,0xA5,0x0D,0x54,0x2B,0x3F,0x58, +0x15,0xC5,0x15,0x5A,0x09,0x1C,0xCD,0xA3,0x9B,0x5F,0x08,0x9C,0x0F,0x9A,0x10,0x44,0x60,0x0C,0x70, +0x0D,0x18,0x9A,0x47,0x02,0x6D,0xC6,0xF6,0x5E,0xF9,0xD8,0x40,0x7D,0x9E,0x37,0x0F,0x30,0x1C,0xD8, +0xE3,0xA3,0x81,0x1A,0x60,0x9F,0xC7,0x82,0x5D,0xE6,0x50,0x9A,0x4C,0x90,0xEA,0x6D,0x22,0xEE,0x67, +0xA0,0x1A,0x98,0x06,0xFC,0x06,0xFA,0x38,0xCA,0x5D,0x03,0x1C,0xB2,0x35,0xE2,0x52,0x49,0x4F,0x3D, +0x8C,0xEE,0x8A,0xA4,0x05,0x92,0x7A,0x49,0x2A,0x49,0x21,0xB7,0xD8,0x3C,0xE7,0x48,0x3A,0x22,0xE9, +0xAB,0x83,0xEC,0xBB,0x2E,0x81,0x6C,0xBD,0xE3,0xC6,0x5B,0x25,0xCD,0xF7,0x88,0xA2,0xF3,0x24,0x7D, +0x72,0x58,0x67,0xB5,0x2D,0x81,0x46,0x07,0xA1,0xED,0x92,0x26,0xF9,0xA6,0x01,0x46,0x1B,0x3F,0x2D, +0xD7,0x6A,0xB4,0x21,0x30,0x5A,0x52,0xDC,0x52,0x60,0xA7,0xA4,0x09,0x21,0x36,0xEF,0xAA,0xF1,0xB8, +0xA4,0x8A,0xE4,0xF7,0x63,0x49,0x6E,0x73,0x05,0x50,0x6A,0x61,0x54,0x1F,0x81,0xB9,0x40,0x4B,0x04, +0x9E,0xA6,0x1E,0x38,0x65,0x31,0xAF,0x14,0x58,0x14,0xE4,0x46,0x87,0x03,0x63,0x2D,0x17,0xDD,0x05, +0x3C,0x88,0xD0,0x5D,0xD6,0x59,0xCE,0x9B,0x1C,0x44,0x60,0x06,0x50,0x69,0x21,0xE4,0x3D,0xB0,0x3D, +0x62,0x7F,0x7F,0x09,0xB8,0x62,0x59,0x7F,0xA4,0x25,0x30,0xD1,0x5C,0xA3,0x4C,0xD8,0x0B,0x74,0x64, +0x21,0x68,0xD9,0x68,0xB4,0xC2,0x54,0x7A,0x29,0x09,0x94,0x03,0x43,0x32,0x08,0x88,0x03,0xFB,0xB3, +0x14,0x75,0x6D,0x34,0x50,0x02,0xF4,0x4D,0x47,0xA0,0x9F,0x99,0x10,0x84,0x5F,0xC0,0x97,0x2C,0x11, +0x68,0xB5,0x98,0xD3,0x03,0xE8,0x95,0x8E,0xC0,0x77,0x13,0xE6,0x03,0xB3,0x6F,0x43,0x22,0x1B,0xB0, +0xAD,0xAC,0x62,0xE9,0x7E,0xBC,0x05,0xDE,0x65,0x78,0xF9,0x37,0xF0,0xC3,0x63,0x73,0x03,0xCD,0x08, +0xC2,0x08,0x1F,0xA2,0x89,0x04,0x9E,0x05,0xA5,0xAD,0x21,0xD1,0x60,0x2A,0xAD,0xB2,0x0C,0x25,0x2B, +0x16,0x57,0xF8,0x5B,0x3A,0x02,0xD7,0x81,0x7B,0x19,0x04,0xF4,0x75,0x6C,0x9F,0x74,0x63,0x14,0x30, +0x1A,0x38,0x17,0x40,0x62,0xB2,0x25,0x81,0xAE,0x74,0x04,0xDE,0x98,0x91,0xC9,0x88,0x56,0x78,0x10, +0xF8,0x69,0x9E,0xD3,0x81,0x0B,0xC6,0x61,0x24,0x62,0xB6,0xA5,0x06,0xF4,0x8F,0xAD,0x24,0xE5,0x16, +0x55,0x16,0x39,0x49,0x9B,0xA4,0x41,0x8E,0xF9,0xCE,0xBD,0x24,0x19,0xF7,0x93,0x5A,0x28,0x27,0x2D, +0xF3,0xA1,0x17,0x92,0x06,0x04,0x25,0x73,0x3D,0x25,0x3D,0xB4,0x10,0xB4,0xC7,0x91,0x40,0x2A,0x99, +0xCD,0xE6,0xBF,0xE5,0x0E,0xD9,0xEF,0xA6,0xA0,0x64,0xAE,0x5B,0xD5,0x0D,0x16,0xAA,0xDC,0x00,0x6C, +0x74,0xB8,0x42,0xB1,0x34,0x69,0xC1,0x7D,0xC7,0xB4,0xE4,0xB6,0x4D,0x45,0x36,0x52,0xD2,0x07,0x8B, +0xD3,0x78,0x6B,0x3A,0x75,0x36,0x1A,0x78,0x1C,0x41,0x9B,0xE5,0x71,0x2A,0xD9,0xA9,0x4E,0xE6,0x15, +0xB0,0xDB,0xE2,0x34,0x0E,0x9A,0xC4,0x2E,0x57,0x68,0x70,0xE9,0x4A,0x6C,0x01,0x5E,0x67,0x10,0x78, +0x35,0x87,0x9B,0xEF,0x30,0x29,0xBC,0x35,0x81,0x0F,0x40,0x6D,0x80,0xC0,0x9D,0xC0,0xF1,0x1C,0x12, +0xD8,0x01,0x74,0xFA,0xB4,0x16,0x37,0xA7,0xB8,0x8B,0x5B,0x3D,0xCA,0xC6,0x96,0x10,0x77,0xBF,0x2E, +0x6C,0x7B,0xFD,0x40,0x42,0xE1,0xBD,0xCD,0xB3,0xEE,0xF5,0x25,0xD0,0x6C,0x5C,0x7B,0x5A,0xD9,0x36, +0xDD,0xE9,0x5A,0xD3,0xA1,0x9B,0x0D,0x6C,0xCA,0x71,0x67,0xEE,0x58,0x42,0x14,0x77,0xEE,0x8D,0x46, +0x89,0x16,0x53,0x4D,0xB9,0xE2,0x97,0x69,0xF0,0x36,0x86,0xFD,0x3E,0x90,0x2F,0xF4,0x00,0xCE,0x02, +0x8B,0x0B,0x95,0x00,0xFC,0xFD,0x02,0x7A,0x06,0x58,0x5A,0xA8,0x04,0xBA,0x71,0x0A,0x58,0x97,0x2F, +0x02,0x37,0x12,0x2A,0xBA,0x30,0xA8,0x74,0x8D,0x03,0x51,0x8D,0x98,0xE9,0x4E,0xD7,0x48,0x7A,0xE9, +0xE9,0x52,0x8F,0x85,0xFD,0x4A,0x19,0x15,0xCA,0x4D,0xF5,0x15,0xB7,0x98,0x5B,0x64,0x6E,0x49,0x31, +0x70,0x33,0x55,0xEE,0x95,0x0F,0x02,0x91,0x22,0x46,0x81,0xE3,0xCF,0x00,0xD2,0xF0,0xF4,0x75,0x05, +0xC1,0xEC,0xA0,0x00,0x00,0x00,0x00,0x49,0x45,0x4E,0x44,0xAE,0x42,0x60,0x82}; diff --git a/archive/blr2/src/main.cpp b/archive/blr2/src/main.cpp new file mode 100644 index 0000000..3c1bec1 --- /dev/null +++ b/archive/blr2/src/main.cpp @@ -0,0 +1,1349 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Main Code +// Copyright Chrisoft 2014 +//Now that we use BSD license, so let's paste it here. +//(although it may be awful) +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + * + */ +//#define Debug +#include <hge.h> +#include <hgefont.h> +#include <hgegui.h> +#include <hgedistort.h> +#include <hgerect.h> +#include <cassert> +#include <cmath> +#include <ctime> +#include <cstdlib> +#include <cstring> +#include <cstdio> +#include <csignal> +#ifdef WIN32 +#include <io.h> +#include <direct.h> +#include <shlwapi.h> +#include <shellapi.h> +#include <windows.h> +#include <mmsystem.h> +#endif +#if defined(__GNUC__) && !defined(MINGW_BUILD) +#include <execinfo.h> +#endif +#include "libcgh.h" +#include "hgeft.h" +#include "global.h" +#include "music.h" +#include "scoresystem.h" +#include "towernbullet.h" +#include "background.h" +#include "levels.h" +#include "scorec.h" +#include "menus.h" +static const char* MAIN_SRC_FN="main.cpp"; +#ifdef WIN32 +void Expand(const char *source,const char *dist) +{ + char cmd[255]; + sprintf(cmd,"%s -F:* %s",source,dist); + int res=(int)ShellExecuteA(NULL,"open","expand.exe",cmd,NULL,SW_HIDE); + if (res<32) Error("Error while decompressing resources!\nCheck if expand.exe works correctly."); +} +void firststartup() +{ + if (MessageBoxA(NULL,"It seems that you are running BLR for the First time!\nLet's do some \ +basic settings first!\n\nUse vsync?","First Start Up",0x00000024)==6) + fpslvl=2; + else + fpslvl=0; + if (MessageBoxA(NULL,"Enable Fullscreen?","First Start Up",0x00000024)==6) + tfs=1; + else + tfs=0; + diffkey=false;VidMode=0; + plrspd=3;plrslospd=3;clrbns=clrmode=0;bgmvol=15;sfxvol=10; + hge->System_Log("%s: Finishing first start up configuraion...",MAIN_SRC_FN); + Options_Writeback(); + Score_Initailize(); +} +#else +void firststartup() +{ + fpslvl=2;tfs=0;VidMode=0;diffkey=false; + plrspd=3;plrslospd=3;clrbns=clrmode=0;bgmvol=15;sfxvol=10; + hge->System_Log("%s: Finishing (stubbed) first start up configuraion...",MAIN_SRC_FN); + Options_Writeback(); + Score_Initailize(); +} +#endif +void Player_Clear_Expand() +{ + if (LOWFPS) + clrrange+=13.6; + else + clrrange+=0.8; + int ds; + for (int i=1;i<=bulcnt;++i) + { + if(bullet[i].bullettype>=253)continue; + double dis=GetDist(bullet[i].bulletpos,playerpos);ds=0; + if(PlayerSplit) + for(int j=1;j<4;++j) + { + if(dis>GetDist(bullet[i].bulletpos,playerpos+splitData[j])) + dis=GetDist(bullet[i].bulletpos,playerpos+splitData[j]),ds=j; + } + if(dis<=clrrange&&bullet[i].exist&&!bullet[i].inv) + { + CreateBullet255(bullet[i].bulletpos.x,bullet[i].bulletpos.y,10,ds); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + } +} +void Player_Clear_Rotate() +{ + if (LOWFPS) + clrrad+=pi/450*17; + else + clrrad+=pi/450; + for (int i=1;i<=bulcnt;++i) + { + if(bullet[i].bullettype>=253)continue; + double dis=GetDist(bullet[i].bulletpos,playerpos); + double rad=atan2l(bullet[i].bulletpos.y-playerpos.y,bullet[i].bulletpos.x-playerpos.x); + hge->Gfx_RenderLine(playerpos.x+8,playerpos.y+8,playerpos.x+cos(clrrad)*clrmaxrange,playerpos.y+sin(clrrad)*clrmaxrange); + rad=normalizerad(rad); + if(dis<=clrmaxrange&&bullet[i].exist&&!bullet[i].inv&&rad>normalizerad(clrrad)-pi/12&&rad<normalizerad(clrrad)+pi/12) + { + CreateBullet255(bullet[i].bulletpos.x,bullet[i].bulletpos.y,10); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + if(PlayerSplit) + for(int j=1;j<4;++j) + { + vector2d plsp=playerpos+splitData[j]; + double dis=GetDist(bullet[i].bulletpos,plsp); + double rad=atan2l(bullet[i].bulletpos.y-plsp.y,bullet[i].bulletpos.x-plsp.x); + hge->Gfx_RenderLine(plsp.x+8,plsp.y+8,plsp.x+cos(clrrad)*clrmaxrange,plsp.y+sin(clrrad)*clrmaxrange); + while (rad<0)rad+=2*pi; + if (bullet[i].bullettype!=255&&dis<=clrmaxrange&&bullet[i].exist&&!bullet[i].inv&&rad>normalizerad(clrrad)-pi/12&&rad<normalizerad(clrrad)+pi/12) + { + CreateBullet255(bullet[i].bulletpos.x,bullet[i].bulletpos.y,10,j); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + } + } +} +void ProcessPlayer() +{ + if (!clrcircle) + { + clrcircle=new hgeSprite(SprSheet,63,71,193,193); + clrcircle->SetHotSpot(96.5f,96.5f); + clrcircle->SetBlendMode(BLEND_ALPHAADD); + } + if(clrmode)clrcircle->SetColor(0x30008080);else clrcircle->SetColor(0x30800000); + if (playerLockX) + { + Lock.Setdata(0,vector2d(playerpos.x-1,0),vector2d(playerpos.x-1,600),0xC0FFFFFF); + for (int i=1;i<80;++i) + Lock.Setdata(i,vector2d(playerpos.x+1,0),vector2d(playerpos.x+1,600),0xC0FFFFFF); + Lock.Render(); + } + if (playerLockY) + { + Lock.Setdata(0,vector2d(0,playerpos.y+5),vector2d(800,playerpos.y+5),0xC0FFFFFF); + for (int i=1;i<80;++i) + Lock.Setdata(i,vector2d(0,playerpos.y+7),vector2d(800,playerpos.y+7),0xC0FFFFFF); + Lock.Render(); + } + if(!PlayerSplit) + playerspr->RenderEx(playerpos.x+8.4,playerpos.y+8.4,playerrot,0.7,0); + else + { + for(int i=0;i<4;++i) + playerspr->RenderEx(playerpos.x+splitData[i].x+8.4,playerpos.y+splitData[i].y+8.4,playerrot,0.7,0); + } + if (DisablePlayer)return; + playerrot+=0.00174533*17; + double realspd; + if (hge->Input_GetKeyState(HGEK_SHIFT)) + realspd=playerslospeed*(1000.0f/hge->Timer_GetFPS()); + else + realspd=playerspeed*(1000.0f/hge->Timer_GetFPS()); + if (hge->Input_GetKeyState(HGEK_LEFT)&&!playerLockX) + if (playerpos.x>10)playerpos.x-=realspd; + if (hge->Input_GetKeyState(HGEK_RIGHT)&&!playerLockX) + if ((playerpos.x<770&&!PlayerSplit)||(playerpos.x<370&&PlayerSplit))playerpos.x+=realspd; + if (hge->Input_GetKeyState(HGEK_UP)&&!playerLockY) + if (playerpos.y>10)playerpos.y-=realspd; + if (hge->Input_GetKeyState(HGEK_DOWN)&&!playerLockY) + if ((playerpos.y<570&&!PlayerSplit)||(playerpos.y<270&&PlayerSplit))playerpos.y+=realspd; + if(mode==2)return; + if (!clrmode) + { + if (hge->Input_GetKeyStateEx(diffkey?HGEK_X:HGEK_Z)==HGEKST_HIT&&clrmaxrange==0) + {clrind=0;charge=1;} + if (hge->Input_GetKeyStateEx(diffkey?HGEK_X:HGEK_Z)==HGEKST_KEEP&&charge) + { + if (clrmaxrange<=400) + {if (LOWFPS)clrmaxrange+=1.6;else clrmaxrange+=0.1;} + if (!LOWFPS)clrind+=0.001*pi;else clrind+=0.016*pi; + clrcircle->RenderEx(playerpos.x+7.2,playerpos.y+7.2,clrind,2*clrmaxrange/193.0f); + if(PlayerSplit)for(int i=1;i<4;++i) + clrcircle->RenderEx(playerpos.x+splitData[i].x+7.2,playerpos.y+splitData[i].y+7.2,clrind,2*clrmaxrange/193.0f); + } + if (hge->Input_GetKeyStateEx(diffkey?HGEK_X:HGEK_Z)==HGEKST_RELEASE&&charge) + { + charge=0; + if (clrmaxrange<=50) + { + if (clrtime+clrbns>0) + {--clrtime;clrmaxrange=350;Player_Clear_Expand();++clrusg;} + else clrmaxrange=0; + } + else{Player_Clear_Expand();++clrusg;} + } + if (clrrange!=0) + { + Player_Clear_Expand(); + clrcircle->RenderEx(playerpos.x+7.2,playerpos.y+7.2,clrind,2*(clrmaxrange-clrrange)/193.0f); + if(PlayerSplit)for(int i=1;i<4;++i) + clrcircle->RenderEx(playerpos.x+splitData[i].x+7.2,playerpos.y+splitData[i].y+7.2,clrind,2*(clrmaxrange-clrrange)/193.0f); + clrind+=(LOWFPS?0.016*pi:0.001*pi); + } + if (clrrange>=clrmaxrange)clrrange=clrmaxrange=0; + } + else + { + if (hge->Input_GetKeyStateEx(diffkey?HGEK_X:HGEK_Z)==HGEKST_HIT&&clrmaxrange==0) + {clrind=0;charge=1;} + if (hge->Input_GetKeyStateEx(diffkey?HGEK_X:HGEK_Z)==HGEKST_KEEP&&charge) + { + if (clrmaxrange<=400) + {if (LOWFPS)clrmaxrange+=1.6;else clrmaxrange+=0.1;} + if (!LOWFPS)clrind+=0.001*pi;else clrind+=0.016*pi; + clrcircle->RenderEx(playerpos.x+7.2,playerpos.y+7.2,clrind,2*clrmaxrange/193.0f); + if(PlayerSplit)for(int i=1;i<4;++i) + clrcircle->RenderEx(playerpos.x+splitData[i].x+7.2,playerpos.y+splitData[i].y+7.2,clrind,2*clrmaxrange/193.0f); + } + if (hge->Input_GetKeyStateEx(diffkey?HGEK_X:HGEK_Z)==HGEKST_RELEASE&&charge) + { + charge=0; + if (clrmaxrange<=50) + { + if(clrtime+clrbns>0) + {--clrtime;clrmaxrange=350;Player_Clear_Rotate();++clrusg;} + else clrmaxrange=0; + }else{Player_Clear_Rotate();++clrusg;} + } + if (clrrad-pi/2>1e-7) + { + Player_Clear_Rotate(); + clrcircle->RenderEx(playerpos.x+7.2,playerpos.y+7.2,clrind,2*clrmaxrange/193.0f*(5*pi/2.0f-clrrad)/(2*pi)); + if(PlayerSplit)for(int i=1;i<4;++i) + clrcircle->RenderEx(playerpos.x+splitData[i].x+7.2,playerpos.y+splitData[i].y+7.2,clrind,2*clrmaxrange/193.0f*(5*pi/2.0f-clrrad)/(2*pi)); + clrind+=(LOWFPS?0.016*pi:0.001*pi); + } + if (5*pi/2-clrrad<1e-7)clrrad=pi/2,clrmaxrange=0; + } +} +void RefreshScore() +{ + Mult_FrameFunc(); + if(DisablePlayer)return; + mult+=0.01f*dsmc; + score+=16*mult; + if(scminus){if(mult/2>0.1)mult/=2;else mult=0.1;} + score+=100*shots*mult; + score-=scminus*mult; + score+=2000*dsmc*mult; + ++frms; + averfps=(averfps*(frms-1)+hge->Timer_GetFPSf())/(double)frms; +} +void CallLevels() +{ + //Use this to call level procedures. + if((mode==1)&&coll!=0){deathMenu.Init(-200);return;} + if((mode==2)&&coll!=0){asts+=assetime;assetime=0;++part;coll=0;IfCallLevel=IfShowTip=true;return;} + if(!IfCallLevel) return; + if(mode==2)assetime+=hge->Timer_GetDelta(); + //Check Complete here + if(level==1&&part==0)Level1Part0(); + if(level==1&&part==1)Level1Part1(); + if(level==1&&part==2)Level1Part2(); + if(level==1&&part==3)Level1Part3(); + if(level==1&&part==4)Level1Part4(); + if(level==2&&part==0)Level2Part0(); + if(level==2&&part==1)Level2Part1(); + if(level==2&&part==2)Level2Part2(); + if(level==2&&part==3)Level2Part3(); + if(level==2&&part==4)Level2Part4(); + if(level==2&&part==5)Level2Part5(); + if(level==2&&part==6)Level2Part6(); + if(level==2&&part==7)Level2Part7(); + if(level==2&&part==8)Level2Part8(); + if(level==2&&part==9)Level2Part9(); + if(level==3&&part==0)Level3Part0(); + if(level==3&&part==1)Level3Part1(); + if(level==3&&part==2)Level3Part2(); + if(level==3&&part==3)Level3Part3(); + if(level==3&&part==4)Level3Part4(); + if(level==3&&part==5)Level3Part5(); + if(level==3&&part==6)Level3Part6(); + if(level==4&&part==0)Level4Part0(); + if(level==4&&part==1)Level4Part1(); + if(level==4&&part==2)Level4Part2(); + if(level==4&&part==3)Level4Part3(); + if(level==4&&part==4)Level4Part4(); + if(level==4&&part==5)Level4Part5(); + if(level==4&&part==6)Level4Part6(); + if(level==4&&part==7)Level4Part7(); + if(level==4&&part==8)Level4Part8(); + if(level==4&&part==9)Level4Part9(); + if(level==4&&part==10)Level4Part10(); + if(level==4&&part==11)Level4Part11(); + if(level==4&&part==12)Level4Part12(); + if(level==4&&part==13)Level4Part13(); + if(level==4&&part==14)Level4Part14(); + if(level==4&&part==15)Level4Part15(); + if(level==4&&part==16)Level4Part16(); + if(level==4&&part==17)Level4Part17(); + if(level==4&&part==18)Level4Part18(); + if(level==4&&part==19)Level4Part19(); + if(level==4&&part==20)Level4Part20(); + if(level==4&&part==21)Level4Part21(); + if(level==4&&part==22)Level4Part22(); + if(level==4&&part==23)Level4Part23(); + if(level==4&&part==24)Level4Part24(); + if(level==4&&part==25)Level4Part25(); + if(level==5&&part==0)Level5Part0(); + if(level==5&&part==1)Level5Part1(); + if(level==5&&part==2)Level5Part2(); + if(level==5&&part==3)Level5Part3(); + if(level==5&&part==4)Level5Part4(); + if(level==5&&part==5)Level5Part5(); + if(level==5&&part==6)Level5Part6(); + if(level==5&&part==7)Level5Part7(); + if(level==5&&part==8)Level5Part8(); + if(level==5&&part==9)Level5Part9(); + if(level==5&&part==10)Level5Part10(); + if(level==5&&part==11)Level5Part11(); + if(level==5&&part==12)Level5Part12(); + if(level==5&&part==13)Level5Part13(); + if(level==5&&part==14)Level5Part14(); + if(level==5&&part==15)Level5Part15(); + if(level==5&&part==16)Level5Part16(); + if(level==5&&part==17)Level5Part17(); + if(level==5&&part==18)Level5Part18(); + if(level==5&&part==19)Level5Part19(); + if(level==5&&part==20)Level5Part20(); + if(level==5&&part==21)Level5Part21(); + if(level==5&&part==22)Level5Part22(); + if(level==6&&part==0)Level6Part0(); + if(level==6&&part==1)Level6Part1(); + if(level==6&&part==2)Level6Part2(); + if(level==6&&part==3)Level6Part3(); + if(level==6&&part==4)Level6Part4(); + if(level==6&&part==5)Level6Part5(); + if(level==6&&part==6)Level6Part6(); + if(level==6&&part==7)Level6Part7(); + if(level==6&&part==8)Level6Part8(); + if(level==6&&part==9)Level6Part9(); + if(level==6&&part==10)Level6Part10(); + if(level==6&&part==11)Level6Part11(); + if(level==6&&part==12)Level6Part12(); + if(level==6&&part==13)Level6Part13(); + if(level==6&&part==14)Level6Part14(); + if(level==6&&part==15)Level6Part15(); + if(level==6&&part==16)Level6Part16(); + if(level==6&&part==17)Level6Part17(); + if(level==6&&part==18)Level6Part18(); + if(level==6&&part==19)Level6Part19(); + if(level==6&&part==20)Level6Part20(); + if(level==6&&part==21)Level6Part21(); + if(level==6&&part==22)Level6Part22(); + if(level==6&&part==23)Level6Part23(); + if(level==6&&part==24)Level6Part24(); + if(level==6&&part==25)Level6Part25(); + if(level==6&&part==26)Level6Part26(); + if(level==6&&part==27)Level6Part27(); + if(level==6&&part==28)Level6Part28(); + if(level==6&&part==29)Level6Part29(); + if(level==6&&part==30)Level6Part30(); + if(level==6&&part==31)Level6Part999999999(); + if(level==7&&part==0)Level7Part0(); + if(level==7&&part==1)Level7Part1(); + if(level==7&&part==2)Level7Part2(); + if(level==7&&part==3)Level7Part3(); + if(level==7&&part==4)Level7Part4(); + if(level==7&&part==5)Level7Part5(); + if(level==7&&part==6)Level7Part6(); + if(level==7&&part==7)Level7Part7(); + if(level==7&&part==8)Level7Part8(); + if(level==7&&part==9)Level7Part9(); + if(level==7&&part==10)Level7Part10(); + if(level==7&&part==11)Level7Part11(); + if(level==7&&part==12)Level7Part12(); + if(level==7&&part==13)Level7Part13(); + if(level==7&&part==14)Level7Part14(); + if(level==7&&part==15)Level7Part15(); + if(level==7&&part==16)Level7Part16(); + if(level==7&&part==17)Level7Part17(); + if(level==7&&part==18)Level7Part18(); + if(level==7&&part==19)Level7Part19(); + if(level==7&&part==20)Level7Part20(); + if(level==7&&part==21)Level7Part21(); + if(level==7&&part==22)Level7Part22(); + if(level==7&&part==23)Level7Part23(); + if(level==7&&part==24)Level7Part24(); + if(level==7&&part==25)Level7Part25(); + if(level==7&&part==26)Level7Part26(); + if(level==-1&&part==0)Levelm1Part0(); + if(level==-1&&part==1)Levelm1Part1(); + if(level==-1&&part==2)Levelm1Part2(); + if(level==-1&&part==3)Levelm1Part3(); + if(level==-1&&part==4)Levelm1Part4(); + if(level==-1&&part==5)Levelm1Part5(); + if(level==-1&&part==6)Levelm1Part6(); + if(level==-1&&part==7)Levelm1Part7(); + if(level==-1&&part==8)Levelm1Part8(); + if(level==-1&&part==9)Levelm1Part9(); + if(level==-1&&part==10)Levelm1Part10(); + if(level==-1&&part==11)Levelm1Part11(); + if(level==-1&&part==12)Levelm1Part12(); + if(level==-1&&part==13)Levelm1Part13(); + if(level==-1&&part==14)Levelm1Part14(); + if(level==-1&&part==15)Levelm1Part15(); + if(level==-1&&part==16)Levelm1Part16(); + if(level==-1&&part==17)Levelm1Part17(); + if(level==-1&&part==18)Levelm1Part18(); + if(level==-1&&part==19)Levelm1Part19(); + if(level==-1&&part==20)Levelm1Part20(); + if(level==-1&&part==21)Levelm1Part21(); + if(level==-2&&part==0)Levelm2Part0(); + if(level==-2&&part==1)Levelm2Part1(); + if(level==-2&&part==2)Levelm2Part2(); + if(level==-2&&part==3)Levelm2Part3(); + if(level==-2&&part==4)Levelm2Part4(); + if(level==-2&&part==5)Levelm2Part5(); + if(level==-2&&part==6)Levelm2Part6(); + if(level==-2&&part==7)Levelm2Part7(); + if(level==-2&&part==8)Levelm2Part8(); + if(level==-2&&part==9)Levelm2Part9(); + if(level==-2&&part==10)Levelm2Part10(); + if(level==-2&&part==11)Levelm2Part11(); + if(level==-2&&part==12)Levelm2Part12(); + if(level==-2&&part==13)Levelm2Part13(); + if(level==-2&&part==14)Levelm2Part14(); + if(level==-2&&part==15)Levelm2Part15(); + if(level==-2&&part==16)Levelm2Part16(); + if(level==-2&&part==17)Levelm2Part17(); + if(level==-2&&part==18)Levelm2Part18(); + if(level==-2&&part==19)Levelm2Part19(); + if(level==-2&&part==20)Levelm2Part20(); + if(level==-2&&part==21)Levelm2Part21(); + if(level==-2&&part==22)Levelm2Part22(); + if(level==-2&&part==23)Levelm2Part23(); + if(level==-2&&part==24)Levelm2Part24(); + if(level==-2&&part==25)Levelm2Part25(); + if(level==-2&&part==26)Levelm2Part26(); + + if(level==1&&part==5)level=2,part=0; + if(level==2&&part==10) + { + if(mode==3&&coll>10){completeMenu.Init(-200);return;} + if(mode==1&&restarts>1){completeMenu.Init(-200);return;} + level=3,part=0; + } + if(level==3&&part==7) + { + if(mode==3&&coll>40){completeMenu.Init(-200);return;} + if(mode==1&&restarts>2){completeMenu.Init(-200);return;} + level=4,part=0; + } + if(level==4&&part==26) + { + if(mode==3&&coll>75){completeMenu.Init(-200);return;} + if(mode==1&&restarts>3){completeMenu.Init(-200);return;} + level=5,part=0; + } + if(level==5&&part==23) + { + if(mode==3&&coll>125){completeMenu.Init(-200);return;} + if(mode==1&&restarts>5){completeMenu.Init(-200);return;} + level=6,part=0; + } + if(level==6&&part==32) + { + if(mode==3&&coll>200){completeMenu.Init(-200);return;} + if(mode==1&&restarts>8){completeMenu.Init(-200);return;} + level=7,part=0; + } + if(level==7&&part==27) + { + if(mode==3&&coll>50){completeMenu.Init(-200);return;} + if(mode==1&&restarts>2){completeMenu.Init(-200);return;} + level=-1,part=0; + } + if(level==-1&&part==22){completeMenu.Init(-200);return;} + if(level==-2&&part>26){completeMenu.Init(-200);return;} +} +bool ProcessCurCred() +{ + CreditsRail->RenderEx(400,300,0,4,1); + if(creditsp!=1) + Credits->Render(creditfly,300); + else + { + Credits->SetTextureRect(4,209,230,76); + Credits->Render(creditfly-30,330); + Credits->SetTextureRect(9,290,140,47); + Credits->Render(creditfly-30,400); + vdig->printf(creditfly-50,240,HGETEXT_LEFT,"%s",BLRVERSION); + bdig->printf(creditfly-50,310,HGETEXT_LEFT,"%s",BuiltDate); + } + if (credstop)credbrk+=hge->Timer_GetDelta(); + if (credbrk>=4.5&&!creddone)creddone=true,credstop=false,creditacc=0,credbrk=0; + if (!credstop)for (int i=1;i<=17;++i)creditfly-=creditacc; + if (creditfly<-300)return true; + for (int i=1;i<=17;++i)if (creditacc<2)creditacc+=0.015; + if (abs(creditfly-400)<5&&!creddone&&!credstop)credstop=true; + return false; +} +void AboutScene() +{ + if (ProcessCurCred()) + creditfly=1200,creditacc=0,credstop=creddone=false,++creditsp, + Credits->SetTextureRect(0,creditsp*200,600,200), + Credits->SetHotSpot(300,100); + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT||creditsp>11) + { + Current_Position=0; + mainMenu.Init(850); + Music_Stop(); + } +} +void HelpScene(bool fake=false) +{ + if(!fake)if(Hlpyofst>0)Hlpyofst-=40;else Hlpyofst=0; + else if(Hlpyofst<400)Hlpyofst+=40;else Hlpyofst=400,hshl=0; + if(Helpslide>1)MenuFont->Render(30,80+Hlpyofst,HGETEXT_LEFT,"Last"), + HlpL->Render(0,85+Hlpyofst); + if(Helpslide<6)MenuFont->Render(770,80+Hlpyofst,HGETEXT_RIGHT,"Next"), + HlpR->Render(775,85+Hlpyofst); + if(Helpscroll==0)Helpspr->Render(0,100+Hlpyofst); + else + { + Helpspr->Render(Helpscroll,100+Hlpyofst); + if(Helpscroll>0)NHelpspr->Render(Helpscroll-800,100+Hlpyofst); + else NHelpspr->Render(Helpscroll+800,100+Hlpyofst); + if(Helpscroll>0)Helpscroll+=30;else Helpscroll-=30; + if(fabs(Helpscroll)>=800) + { + Helpscroll=0;Helpspr->SetTextureRect(0,400*(Helpslide-1),800,400); + } + } + if(fake)return; + if(Helpscroll==0) + { + if(hge->Input_GetKeyStateEx(HGEK_LEFT)==HGEKST_HIT&&Helpslide>1) + { + --Helpslide;NHelpspr->SetTextureRect(0,400*(Helpslide-1),800,400); + Helpscroll=1; + } + if(hge->Input_GetKeyStateEx(HGEK_RIGHT)==HGEKST_HIT&&Helpslide<6) + { + ++Helpslide;NHelpspr->SetTextureRect(0,400*(Helpslide-1),800,400); + Helpscroll=-1; + } + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT) + { + Current_Position=0;mainMenu.Init(1000);hshl=1; + } + } +} +bool Foclost() +{ + if(Current_Position==1)pauseMenu.Init(-200); + return false; +} +bool FrameFunc() +{ + float dt=hge->Timer_GetDelta(); + static float t=0.0f; + float tx,ty; + if (Current_Position==1&&hge->Input_GetKeyState(HGEK_ESCAPE))pauseMenu.Init(-200); + int MMR=-1,SMR=-1,OMR=-1,PPMR=-1,PMR=-1,RTTMR=-1,DMR=-1,CMR=-1,HSMR=-1,HSVMR=-1,HSDMR=-1; + if (mainMenu.isActive())MMR=mainMenu.Update(); + if (startMenu.isActive())SMR=startMenu.Update(); + if (optionMenu.isActive())OMR=optionMenu.Update(); + if (playerPreferenceMenu.isActive())PPMR=playerPreferenceMenu.Update(); + if (pauseMenu.isActive())PMR=pauseMenu.Update(); + if (returnToTitleMenu.isActive())RTTMR=returnToTitleMenu.Update(); + if (deathMenu.isActive())DMR=deathMenu.Update(); + if (completeMenu.isActive())CMR=completeMenu.Update(); + if (newHighScoreGUI.isActive())newHighScoreGUI.Update(); + if (highScoreMenu.isActive())HSMR=highScoreMenu.Update(); + if (highScoreViewMenu.isActive())HSVMR=highScoreViewMenu.Update(); + if (highScoreDetailsMenu.isActive())HSDMR=highScoreDetailsMenu.Update(); + if (Current_Position==0) + { + if(!mainMenu.isActive())return true; + if(~MMR) + { + switch(MMR) + { + case 0:Current_Position=3;startMenu.Init();mainMenu.Leave();break; + case 1:Current_Position=8;highScoreMenu.Init(-200);mainMenu.Leave();break; + case 2: + Current_Position=13; + optionMenu.Init(-200); + break; + case 3: + Current_Position=15; + Helpspr->SetTextureRect(0,0,800,400); + NHelpspr->SetTextureRect(0,400,800,400); + Helpslide=1;Hlpyofst=400;Helpscroll=0; + break; + case 4: + Credits->SetHotSpot(300,100); + CreditsRail->SetHotSpot(300,100); + creditsp=0; + Music_Init("./Resources/Music/BLR2_TR09.ogg"); + lpst=lped=0;Music_Play(); + creditfly=1200;creditacc=0;credstop=creddone=false; + Credits->SetTextureRect(0,0,600,200); + Current_Position=4; + mainMenu.Leave(); + break; + case 5:break; + } + mainMenu.Leave(); + return false; + } + } + if (Current_Position==3) + { + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT) + { + startMenu.Leave();mainMenu.Init(800);Current_Position=0; + } + if(~SMR) + { + startMenu.Leave(); + switch(SMR) + { + case 0: + playerpos.x=400,playerpos.y=400,playerrot=0; + frameleft=ThirtySeconds;infofade=0xFF;Dis8ref=t8special=false; + level=1,part=1;frms=0,averfps=0.0;bsscale=1; + if(bullet){free(bullet);bullet=NULL;} + towcnt=bulcnt=0;whrcnt=12;skyactive=false;PlayerSplit=false; + score=0;Mult_Init();//Music_Init("./Resources/Music/CanonTechno.ogg"); + lpst=4607901;lped=9215893;//Music_Play(); + coll=semicoll=clrusg=0;playerLockX=playerLockY=false; + Lock.Init(2);IfShowTip=true;lsc=0; + clrrad=pi/2;clrrange=0;re.SetSeed(time(NULL)); + FadeTip=false;memset(lasttip,0,sizeof(lasttip)); + memset(tower,0,sizeof(tower)); + Complete=false; + Current_Position=1; + Level1Part1(); + IfCallLevel=true; + mode=1; + break; + case 1: + playerpos.x=400,playerpos.y=400,playerrot=0; + frameleft=ThirtySeconds;infofade=0xFF;Dis8ref=t8special=false; + level=-2,part=0;frms=0,averfps=0.0;bsscale=1;assetime=asts=0; + if(bullet){free(bullet);bullet=NULL;} + towcnt=bulcnt=0;whrcnt=12;skyactive=false;PlayerSplit=false; + score=0;Mult_Init();Music_Init("./Resources/Music/CanonTechno.ogg"); + lpst=4607901;lped=9215893;Music_Play(); + coll=semicoll=clrusg=0;playerLockX=playerLockY=false; + Lock.Init(2);IfShowTip=true;lsc=0; + clrrad=pi/2;clrrange=0;re.SetSeed(time(NULL)); + FadeTip=false;memset(lasttip,0,sizeof(lasttip)); + memset(tower,0,sizeof(tower)); + Complete=false; + Current_Position=1; + IfCallLevel=true; + mode=2; + break; + case 2: + playerpos.x=400,playerpos.y=400,playerrot=0; + frameleft=ThirtySeconds;infofade=0xFF;Dis8ref=t8special=false; + level=1,part=1;frms=0,averfps=0.0;bsscale=1; + if(bullet){free(bullet);bullet=NULL;} + towcnt=bulcnt=0;whrcnt=12;skyactive=false;PlayerSplit=false; + score=0;Mult_Init();//Music_Init("./Resources/Music/CanonTechno.ogg"); + lpst=4607901;lped=9215893;//Music_Play(); + coll=semicoll=clrusg=0;playerLockX=playerLockY=false; + Lock.Init(2);IfShowTip=true;lsc=0; + clrrad=pi/2;clrrange=0;re.SetSeed(time(NULL)); + FadeTip=false;memset(lasttip,0,sizeof(lasttip)); + memset(tower,0,sizeof(tower)); + Complete=false; + Current_Position=1; + Level1Part1(); + IfCallLevel=true; + mode=3; + break; + } + return false; + } + } + if (Current_Position==5) + { + if(~DMR) + { + if(DMR==1) + { + IfCallLevel=true; + IfShowTip=true; + Current_Position=1; + score=-abs(score); + mult=1;multbat=1;multbrk=TenSeconds; + ++restarts;part=0; + clockrot=deltarot=0; + coll=towcnt=bulcnt=0; + DisableAllTower=DisablePlayer=false; + } + if(DMR==2) + {Current_Position=0;mainMenu.Init(-200);} + deathMenu.Leave(); + return false; + } + } + if (Current_Position==6) + { + if(~CMR) + { + if(CMR==1) + {Current_Position=7;newHighScoreGUI.Init();} + if(CMR==2) + {Current_Position=0;mainMenu.Init(-200);} + completeMenu.Leave(); + return false; + } + } + if (Current_Position==8) + { + if(~HSMR) + { + if(HSMR<=2) + {Current_Position=9;highScoreViewMenu.Init(-200,HSMR);} + if(HSMR==3) + {Current_Position=0;mainMenu.Init(-200);} + highScoreMenu.Leave(); + return false; + } + } + if (Current_Position==9) + { + if(~HSVMR) + { + if(HSVMR<=highScoreViewMenu.GetViewCount()&&HSVMR) + {Current_Position=10;highScoreDetailsMenu.Init(-200,highScoreViewMenu.View(),HSVMR);} + if(HSVMR==6) + {Current_Position=8;highScoreMenu.Init(-200);} + if(HSVMR&&(HSVMR<=highScoreViewMenu.GetViewCount()||HSVMR==6)) + highScoreViewMenu.Leave(); + return false; + } + } + if (Current_Position==10) + { + if(~HSDMR) + { + highScoreViewMenu.Init(-200,highScoreDetailsMenu.View()); + highScoreDetailsMenu.Leave();Current_Position=9; + return false; + } + } + if (Current_Position==11) + { + //I am cornered!! + if(!pauseMenu.isActive())Current_Position=1,DisableAllTower=DisablePlayer=0; + if(~PMR) + { + pauseMenu.Leave(); + if(PMR==2)returnToTitleMenu.Init(-200),Current_Position=12; + else Music_Resume(); + return false; + } + } + if (Current_Position==12) + { + if(~RTTMR) + { + returnToTitleMenu.Leave(); + if(RTTMR==1)pauseMenu.Init(-200); + if(RTTMR==2)mainMenu.Init(-200),Current_Position=0; + } + } + if (Current_Position==13) + { + if(~OMR) + { + if(OMR==6||OMR==7)optionMenu.Leave(); + if(OMR==6) + { + playerPreferenceMenu.Init(-200); + Current_Position=14; + } + if(OMR==7) + { + Options_Writeback(); + mainMenu.Init(-200); + Current_Position=0; + } + return false; + } + } + if (Current_Position==14) + { + if(~PPMR) + { + if(PPMR==5) + { + if(AP_Update(plrspd,plrslospd,clrbns)<=10000) + optionMenu.Init(850), + Current_Position=13, + playerPreferenceMenu.Leave(); + else playerPreferenceMenu.Shake(); + } + return false; + } + } + t+=dt; + tx=50*cosf(t/60); + ty=50*sinf(t/60); + quad.v[0].tx=tx; quad.v[0].ty=ty; + quad.v[1].tx=tx+800/64; quad.v[1].ty=ty; + quad.v[2].tx=tx+800/64; quad.v[2].ty=ty+600/64; + quad.v[3].tx=tx; quad.v[3].ty=ty+600/64; + //Rendering*********************************************************************************** + //Super Spliter!*****Super Spliter!*****Super Spliter!*****Super Spliter!*****Super Spliter!** + //******Super Spliter!*****Super Spliter!*****Super Spliter!*****Super Spliter!*************** + hge->Gfx_BeginScene(); +#ifndef WIN32 + hge->Gfx_SetTransform(0,0,0,yos,0,scale,scale); +#else + hge->Gfx_SetTransform(0,0,0,0,0,scale,scale); +#endif + for(int i=0;i<4;i++)quad.v[i].col=DBGColor; + hge->Gfx_Clear(SETA(DBGColor,0xFF)); + if (skyactive)sky.Update(),sky.Render(); + hge->Gfx_RenderQuad(&quad); + int bulinuse=0; + if (Current_Position==1||Current_Position==2||Current_Position==5||Current_Position==11||Current_Position==12) + { + //If we are at the main scene or tip scene(which towers and bullets should still appear..) + //Render towers, bullets and player. + if (Leaves.IsActive())Leaves.Update(); + if (binter.active())binter.Update(); + if (bdiff.active())bdiff.Update(); + if (LE_Active)Leaf.Update(); + shots=0; + dsmc=scminus=0; + Music_Update(); + ProcessTower1(); + ProcessTower2(); + ProcessTower3(); + ProcessTower4(); + ProcessTower5(); + ProcessTower6(); + ProcessTower7(); + ProcessTower8(); + ProcessTower9(); + ProcessLaser(); + for (int i=1;i<=bulcnt;++i) + { + if(bullet[i].exist)++bulinuse; + switch (bullet[i].bullettype) + { + case 1:ProcessBullet1(i);break; + case 2:ProcessBullet2(i);break; + case 4:ProcessBullet4(i);break; + case 5:ProcessBullet5(i);break; + case 6:ProcessBullet6(i);break; + case 7:ProcessBullet7(i);break; + case 8:ProcessBullet8(i);break; + case 9:ProcessBullet9(i);break; + case 253:BulletDeath_Process(i);break; + case 254:SCEffect_Process(i);break; + case 255:ProcessBullet255(i);break; + } + } + if (Current_Position==1)CallLevels(); + ProcessPlayer(); + RefreshScore(); + { + if (ATarg.visible)ATarg.TargFollowPlayer(),ATarg.TargRender(); + } + { + if (BTarg.visible)BTarg.TargRender(); + } + if (!DisablePlayer)--frameleft; + if (!LOWFPS) + { + if (playerspeed<playerfulspd)playerspeed+=playerfulspd/400; + if (playerslospeed<playerfulslospd)playerslospeed+=playerfulslospd/400; + } + else + { + if (playerspeed<playerfulspd)playerspeed+=playerfulspd/25; + if (playerslospeed<playerfulslospd)playerslospeed+=playerfulslospd/25; + } + } + if (frameleft==0&&Current_Position==1) + { + IfCallLevel=true; + ++part; + IfShowTip=true; + } + if(Current_Position==1&&shots)hge->Effect_PlayEx(snd,sfxvol/15.0,0,1,false); + if(mainMenu.isActive())mainMenu.Render(); + if(startMenu.isActive())startMenu.Render(); + if(optionMenu.isActive())optionMenu.Render(); + if(playerPreferenceMenu.isActive())playerPreferenceMenu.Render(); + if(pauseMenu.isActive())pauseMenu.Render(); + if(returnToTitleMenu.isActive())returnToTitleMenu.Render(); + if(deathMenu.isActive())deathMenu.Render(); + if(completeMenu.isActive())completeMenu.Render(); + if(newHighScoreGUI.isActive())newHighScoreGUI.Render(); + if(highScoreMenu.isActive())highScoreMenu.Render(); + if(highScoreViewMenu.isActive())highScoreViewMenu.Render(); + if(highScoreDetailsMenu.isActive())highScoreDetailsMenu.Render(); + if(Current_Position==15)HelpScene();if(hshl)HelpScene(1); + if(Current_Position==0||Current_Position==3||Current_Position==8|| + Current_Position==9||Current_Position==10||Current_Position==13||Current_Position==14) + { + titlespr->Render(160,0); + } + if (Current_Position==2)ShowTip(lasttip); + if (Current_Position==4)AboutScene(); + fnt->SetColor(0xFFFFFFFF); + rbPanelFont.UpdateString(L" FPS: %.2f",hge->Timer_GetFPSf()); + rbPanelFont.Render(785,595,0xFFFFFFFF,1); + if (Current_Position==1||Current_Position==2) + { + rbPanelFont.UpdateString(L"AF: %.2f",averfps); + rbPanelFont.Render(785,575,0xFFFFFFFF,1); + if (playerpos.x<220&&playerpos.y<200) + { + if (!LOWFPS&&infofade>=0x33)--infofade; + if (LOWFPS&&infofade>0x33)infofade-=16; + } + else + { + if (!LOWFPS&&infofade<0xFF)++infofade; + if (LOWFPS&&infofade<=0xEF)infofade+=16; + } + if(hge->Input_GetKeyStateEx(HGEK_A)==HGEKST_HIT)showdebug^=1; + if(showdebug) + { + fnt->SetColor(0xFFFFFFFF); + fnt->printf(795, 0, HGETEXT_RIGHT, "Allocated bullets %d",bulcnt); + fnt->printf(795, 25, HGETEXT_RIGHT, bulcnt?"%d in use (%.2f%%)":"%d in use (?%)",bulinuse,(double)bulinuse/bulcnt); + fnt->printf(795, 50, HGETEXT_RIGHT, "Player pos (%.2f,%.2f)",playerpos.x,playerpos.y); + } + fnt->SetColor(SETA(0xFFFFFF,infofade)); + fnt->printf(5, 0, HGETEXT_LEFT, "Frames to go: %d",frameleft); + fnt->printf(5, 25, HGETEXT_LEFT, "Score: %lld",score); + fnt->printf(5, 50, HGETEXT_LEFT, "Level %d",level); + if (mode==3) + fnt->printf(5, 75, HGETEXT_LEFT, "Collisions: %d",coll); + else if (mode==2) + fnt->printf(5, 75, HGETEXT_LEFT, "Elapsed Time: %.2lf",assetime); + else + fnt->printf(5, 75, HGETEXT_LEFT, "Restarts: %d",restarts); + fnt->printf(5, 100, HGETEXT_LEFT, "Semi-Collisions: %d",semicoll); + if(mode==2) + fnt->printf(5, 125, HGETEXT_LEFT, "Multiplier: %.2lf",mult); + else + { + fnt->printf(5, 125, HGETEXT_LEFT, "Clear Range Left: %d",clrtime+clrbns); + fnt->printf(5, 150, HGETEXT_LEFT, "Multiplier: %.2lf",mult); + } + } + hge->Gfx_EndScene(); + if(hge->Input_GetKeyStateEx(HGEK_S)==HGEKST_HIT&&Current_Position!=7)hge->System_Snapshot(); + return false; +} +void printHelp(char *exec,const char* str="") +{ + printf("Usage: %s [options]...\n",exec); + puts("To run the game normally, just start without arguments."); + puts("Options:"); + puts("--help Print this help and exit."); + puts("--version Print version and exit."); + puts("--start=x,y Start free play mode directly from level x part y. The part must be valid."); + puts("--nosound Forcibly use no sound."); + puts("--fullscreen=1/0 Forcibly use fullscreen/windowed. This will override your configuration."); + puts("--vidmode=0~4 Forcibly use specific video mode instead the one in the configuration."); + puts(" 0 800x600 (native resolution)"); + puts(" 1 640x480"); + puts(" 2 960x720"); + puts(" 3 1024x768"); + puts(" 4 1280x960"); + puts("--firststartup Forcibly run first start up. The score file will be preserved if exist."); + puts("--fast Fast mode. All levels are two times shorter."); + puts("--logfile=... Use an alternate log file name instead of the default \"BLRLOG.txt\"."); +#ifdef WIN32 + puts("--nohideconsole Do not hide console.\n"); +#endif + if(strcmp(str,""))printf("%s\n",str); + exit(0); +} +void parseArgs(int argc,char *argv[]) +{ + for(int i=1;i<argc;++i) + { + if(!strcmp(argv[i],"--help"))printHelp(argv[0]); + if(!strcmp(argv[i],"--version")) + { + printf("Bullet Lab Remix II %s\n",BLRVERSION); + printf("Built Date: %s\n",BuiltDate); + exit(0); + } + bool valid=false; + if(!strcmp(argv[i],"--nosound"))fNoSound=true,valid=true; + if(!strcmp(argv[i],"--fast"))fFast=true,valid=true; + if(!strcmp(argv[i],"--firststartup"))fFristStartUp=true,valid=true; + if(!strncmp(argv[i],"--fullscreen",12)) + { + char *ptr=argv[i];while(*ptr!='='&&*ptr)++ptr; + if(!*ptr)printHelp(argv[0],"--fullscreen need a parameter!\n"); + ++ptr; + int para=strtol(ptr,&ptr,10); + if(*ptr||(para!=1&¶!=0))printHelp(argv[0],"Invalid parameter for --fullscreen!\n"); + if(para)fFullScreen=2;else fFullScreen=1; + valid=true; + } + if(!strncmp(argv[i],"--vidmode",9)) + { + char *ptr=argv[i];while(*ptr!='='&&*ptr)++ptr; + if(!*ptr)printHelp(argv[0],"--vidmode need a parameter!\n"); + ++ptr; + int para=strtol(ptr,&ptr,10); + if(*ptr||(para<0||para>4))printHelp(argv[0],"Invalid parameter for --vidmode!\n"); + if(para)VidMode=para; + valid=true; + } + if(!strncmp(argv[i],"--start",7)) + { + char *ptr=argv[i];while(*ptr!='='&&*ptr)++ptr; + if(!*ptr)printHelp(argv[0],"--start need two parameters!"); + ++ptr;startLvl=strtol(ptr,&ptr,10); + if(*ptr!=',')printHelp(argv[0],"Invalid parameter for --start!\n"); + ++ptr;startPrt=strtol(ptr,&ptr,10); + if(*ptr)printHelp(argv[0],"Invalid parameter for --start!\n"); + valid=true; + } + if(!strncmp(argv[i],"--logfile",9)) + { + char *ptr=argv[i];while(*ptr!='='&&*ptr)++ptr; + if(!*ptr)printHelp(argv[0],"--logfile need a parameter!"); + ++ptr;strcpy(alterLog,ptr); + valid=true; + } +#ifdef WIN32 + if(!strncmp(argv[i],"--nohideconsole",15))noHideConsole=true,valid=true; +#endif + if(!valid) + { + char err[256];sprintf(err,"Unknown option: %s\n",argv[i]); + printHelp(argv[0],err); + } + } +} +int main(int argc,char *argv[]) +{ + signal(SIGSEGV,SigHandler); + parseArgs(argc,argv); +#ifdef WIN32 + if(!noHideConsole)FreeConsole(); +#endif + srand(time(NULL)); + hge=hgeCreate(HGE_VERSION); + if(alterLog[0]) + hge->System_SetState(HGE_LOGFILE, alterLog); + else + hge->System_SetState(HGE_LOGFILE, "BLRLOG.txt"); + hge->System_Log("%s: Bullet Lab Remix Log File",MAIN_SRC_FN); +#ifdef WIN32 +#ifdef MINGW_BUILD + hge->System_Log("%s: Build: MinGW_w64 cross build",MAIN_SRC_FN); +#else + hge->System_Log("%s: Build: Win32 build",MAIN_SRC_FN); +#endif +#else + hge->System_Log("%s: Build: Unix build",MAIN_SRC_FN); +#endif + hge->System_Log("%s: Version: %s",MAIN_SRC_FN,BLRVERSION); + hge->System_Log("%s: Built Date: %s",MAIN_SRC_FN,BuiltDate); +#ifdef WIN32 + if (_mkdir("./Resources")!=0||_mkdir("./Resources/Music")!=0) + Error("Cannot decompress resources!\nDetailed Information: An error occured while creating folder.\n\nTry restarting the game."); + hge->System_Log("%s: Folders created successfully.",MAIN_SRC_FN); + Expand("BLRData.dtp","Resources"); + Expand("BLRMusic.dtp","Resources/Music"); + hge->System_Log("%s: Resources decompressed successfully.",MAIN_SRC_FN); +#endif + hge->System_SetState(HGE_FRAMEFUNC, FrameFunc); + hge->System_SetState(HGE_FOCUSLOSTFUNC, Foclost); + hge->System_SetState(HGE_DONTSUSPEND, true); + hge->System_SetState(HGE_TITLE, "Bullet Lab Remix"); + hge->System_SetState(HGE_WINDOWED, true); + hge->System_SetState(HGE_SCREENWIDTH, 800); + hge->System_SetState(HGE_SCREENHEIGHT, 600); + hge->System_SetState(HGE_SCREENBPP, 32); + if(fNoSound)hge->System_SetState(HGE_USESOUND,false); +#ifdef WIN32 + hge->System_SetState(HGE_ICON, MAKEINTRESOURCE(1)); +#endif + if((access(".blrrc",R_OK))==-1) + { + hge->System_Log("%s: Config file not found. Calling first startup.",MAIN_SRC_FN); + firststartup(); + } + if(fFristStartUp)firststartup(); + hge->System_Log("%s: Loading config file",MAIN_SRC_FN); + freopen(".blrrc","r",stdin); + char tch=getchar(); + if (tch!=';'){} + tch=getchar(); + if (tch!='C'){} + tch=getchar(); + if (tch!='B'){} + tch=getchar(); + if (tch!='L'){} + fpslvl=0; + LOWFPS=true;//always LowFPS, deprecate 1000 FPS mode... + hge->System_SetState(HGE_FPS,61); + tch=getchar();//VSync + if (tch==1) + { + hge->System_SetState(HGE_FPS,HGEFPS_VSYNC); + fpslvl=2; + } + if(fFast)TenSeconds/=2,TwentySeconds/=2,ThirtySeconds/=2,AMinute/=2; + tch=getchar();//FULLSCRREEN + tfs=false; + if (tch==1) + hge->System_SetState(HGE_WINDOWED, false),tfs=true; + if(fFullScreen==2)hge->System_SetState(HGE_WINDOWED, false),tfs=true; + if(fFullScreen==1)hge->System_SetState(HGE_WINDOWED, true),tfs=false; + tch=getchar();//resolution + if(VidMode==-1)VidMode=tch; + switch(VidMode) + { + case 0:break; + case 1: + hge->System_SetState(HGE_SCREENWIDTH, 640); + hge->System_SetState(HGE_SCREENHEIGHT, 480); + break; + case 2: + hge->System_SetState(HGE_SCREENWIDTH, 960); + hge->System_SetState(HGE_SCREENHEIGHT, 720); + break; + case 3: + hge->System_SetState(HGE_SCREENWIDTH, 1024); + hge->System_SetState(HGE_SCREENHEIGHT, 768); + break; + case 4: + hge->System_SetState(HGE_SCREENWIDTH, 1280); + hge->System_SetState(HGE_SCREENHEIGHT, 960); + break; + } + scale=VidMode?VidMode==1?0.8:VidMode==2?1.2:VidMode==3?1.28:VidMode==4?1.6:0:1; +#ifndef WIN32 + yos=VidMode?VidMode==1?120:VidMode==2?-120:VidMode==3?-168:VidMode==4?-360:0:0; +#endif + tch=getchar();//Key binding + if (tch==1)diffkey=true; + bgmvol=getchar();sfxvol=getchar(); + plrspd=tch=getchar(); + playerfulspd=(tch)*0.08f; + playerspeed=playerfulspd; + plrslospd=tch=getchar(); + playerfulslospd=(tch)*0.02f; + playerslospeed=playerfulslospd; + tch=getchar(); + clrbns=tch; + tch=getchar(); + clrmode=tch; + fclose(stdin); + if (AP_Update(plrspd,plrslospd,clrbns)>10000)Error("Invalid configuration!\nTry removing .blrrc and run the game again."); + hge->System_Log("%s: Loading Score file",MAIN_SRC_FN); + Score_Init(); +#ifdef Debug + playerspeed=playerfulspd=0.2; + playerslospeed=playerfulslospd=0.05; +#endif + Current_Position=0; + LE_Active=false; + if(hge->System_Initiate()) + { + hge->System_Log("%s: Loading Resources...",MAIN_SRC_FN); + quad.tex=hge->Texture_Load("./Resources/b_null.png"); + SprSheet=hge->Texture_Load("./Resources/ss.png"); + TLeaf=hge->Texture_Load("./Resources/e_leaf.png"); + TSflake=hge->Texture_Load("./Resources/e_sflake.png"); + TexTitle=hge->Texture_Load("./Resources/title.png"); + TexCredits=hge->Texture_Load("./Resources/credits.png"); + MenuTex=hge->Texture_Load("./Resources/menus.png"); + HelpTex=hge->Texture_Load("./Resources/help.png"); + sky.Init(); + snd=hge->Effect_Load("./Resources/tap.ogg"); + menumov=hge->Effect_Load("./Resources/tap.ogg"); + menuin=hge->Effect_Load("./Resources/tap.ogg"); + menuout=hge->Effect_Load("./Resources/tap.ogg"); + if(!quad.tex||!SprSheet||!TexTitle||!TexCredits) + Error("Error Loading Resources!",true); + titlespr=new hgeSprite(TexTitle,0,0,640,320); + playerspr=new hgeSprite(SprSheet,0,24,24,24); + playerspr->SetHotSpot(12,12); + playerspr->SetColor(0xC0FFFFFF); + ATarg.Init(-0.001,vector2d(400,300)); + BTarg.Init(-0.001,vector2d(400,300)); + BTarg.targspr->SetColor(0xFFC00000); + quad.blend=BLEND_ALPHABLEND | BLEND_COLORMUL | BLEND_NOZWRITE; + DBGColor=0xFFFFFFFF; + for(int i=0;i<4;i++) + { + quad.v[i].z=0.5f; + quad.v[i].col=DBGColor; + } + quad.v[0].x=0; quad.v[0].y=0; + quad.v[1].x=800; quad.v[1].y=0; + quad.v[2].x=800; quad.v[2].y=600; + quad.v[3].x=0; quad.v[3].y=600; + hge->System_Log("%s: Loading Fonts...",MAIN_SRC_FN); +#ifdef WIN32 + if(!rbPanelFont.Init("C:/Windows/Fonts/cour.ttf",18))return 1; +#else + if(!rbPanelFont.Init("/usr/share/fonts/truetype/freefont/FreeMono.ttf",18)) + if(!rbPanelFont.Init("/usr/share/fonts/TTF/FreeMono.ttf",18))return 1; +#endif + fnt=new hgeFont("./Resources/charmap.fnt"); + MenuFont=new hgeFont("./Resources/charmap.fnt"); + TipFont=new hgeFont("./Resources/charmap.fnt"); + MultFnt=new hgeFont("./Resources/charmap.fnt"); + vdig=new hgeFont("./Resources/vdig.fnt"); + bdig=new hgeFont("./Resources/bdig.fnt"); + fnt->SetScale(0.8); + MenuFont->SetScale(0.8); + TipFont->SetScale(0.8); + MultFnt->SetScale(0.8); + spr=new hgeSprite(SprSheet,216,0,24,24); + Credits=new hgeSprite(TexCredits,0,0,600,200); + CreditsRail=new hgeSprite(TexCredits,0,2400,600,200); + Helpspr=new hgeSprite(HelpTex,0,0,800,400); + NHelpspr=new hgeSprite(HelpTex,0,0,800,400); + HlpL=new hgeSprite(MenuTex,256,320,26,15); + HlpR=new hgeSprite(MenuTex,256,335,26,15); + for (int ii=0;ii<COLOR_COUNT;++ii) + { + TColors i=(TColors)ii; + TextureRect a=GetTextureRect(0,i); + bulletspr[i]=new hgeSprite(SprSheet,a.x,a.y,a.w,a.h); + bulletspr[i]->SetHotSpot(12,12);bulletspr[i]->SetColor(0x80FFFFFF); + } + for (int ii=0;ii<grey;++ii) + { + TColors i=(TColors)ii; + TextureRect a=GetTextureRect(1,i); + towerspr[i]=new hgeSprite(SprSheet,a.x,a.y,a.w,a.h); + towerspr[i]->SetHotSpot(22,22);bulletspr[i]->SetColor(0x80FFFFFF); + } + mainMenu.Init_Once();if(!startLvl)mainMenu.Init(-200); + startMenu.Init_Once();optionMenu.Init_Once(); + pauseMenu.Init_Once();returnToTitleMenu.Init_Once(); + deathMenu.Init_Once();completeMenu.Init_Once(); + playerPreferenceMenu.Init_Once();highScoreMenu.Init_Once(); + highScoreViewMenu.Init_Once();highScoreDetailsMenu.Init_Once(); + if(fNoSound)hge->System_Log("%s: Sound is disabled.",MAIN_SRC_FN); + if(startLvl) + { + hge->System_Log("%s: Starting from Level%dPart%d",MAIN_SRC_FN,startLvl,startPrt); + playerpos.x=400,playerpos.y=400,playerrot=0; + frameleft=ThirtySeconds;infofade=0xFF;Dis8ref=t8special=false; + level=startLvl,part=startPrt;frms=0,averfps=0.0;bsscale=1;DBGColor=0xFF000000; + if(bullet){free(bullet);bullet=NULL;} + towcnt=bulcnt=0;whrcnt=12;skyactive=false;PlayerSplit=false; + score=0;Mult_Init();Music_Init("./Resources/Music/BLR2_TR07.ogg"); + lpst=0;lped=0;Music_Play(); + coll=semicoll=clrusg=0;playerLockX=playerLockY=false; + Lock.Init(2);IfShowTip=true;lsc=0; + clrrad=pi/2;clrrange=0;re.SetSeed(time(NULL)); + memset(tower,0,sizeof(tower)); + Complete=false;Current_Position=1; + IfCallLevel=true; + mode=3; + } + hge->System_Start(); + delete titlespr;delete fnt; + delete playerspr;delete spr; + for (int ii=0;ii<COLOR_COUNT;++ii) + { + TColors i=(TColors)ii; + delete bulletspr[i]; + if(i<grey)delete towerspr[i]; + } + hge->Effect_Free(snd);hge->Effect_Free(menuin); + hge->Effect_Free(menuout);hge->Effect_Free(menumov); + hge->Texture_Free(SprSheet);hge->Texture_Free(TLeaf); + hge->Texture_Free(quad.tex);hge->Texture_Free(TSflake); + hge->Texture_Free(TexTitle);hge->Texture_Free(TexCredits); + if(bullet){free(bullet);bullet=NULL;} + } + hge->System_Shutdown(); + hge->Release(); +#ifdef WIN32 + for(int i=0;i<arFilecount;++i)remove(archive[i]); + _rmdir("./Resources/Music"); + _rmdir("./Resources"); +#endif + return 0; +} diff --git a/archive/blr2/src/menus.h b/archive/blr2/src/menus.h new file mode 100644 index 0000000..30d8b0a --- /dev/null +++ b/archive/blr2/src/menus.h @@ -0,0 +1,1536 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Menu Implementations +// Copyright Chrisoft 2014 +// The menu rewrite is almost complete... +//static const char* MENUS_H_FN="menus.h"; +void TriggerSound(int type) +{ + switch(type) + { + case 0:hge->Effect_PlayEx(menumov,sfxvol/15.0,0,1,false);break; + case 1:hge->Effect_Play(menuin);break; + case 2:hge->Effect_Play(menuout);break; + } +} +void ConfigureQuad(hgeQuad *quad,double x,double y,double w,double h) +{ + quad->tex=0;quad->blend=BLEND_ALPHABLEND; + quad->v[0].tx=0;quad->v[0].ty=0; + quad->v[1].tx=1;quad->v[1].ty=0; + quad->v[2].tx=1;quad->v[2].ty=1; + quad->v[3].tx=0;quad->v[3].ty=1; + quad->v[0].x=x;quad->v[0].y=y; + quad->v[1].x=x+w;quad->v[1].y=y; + quad->v[2].x=x+w;quad->v[2].y=y+h; + quad->v[3].x=x;quad->v[3].y=y+h; +} +int AP_Update(int plrspd,int plrslospd,int clrbns) +{ + int res=0; + if (plrspd<=4)res+=plrspd*1200;else res+=5000; + switch (plrslospd) + { + case 1:res+=4000;break; + case 2:res+=3200;break; + case 3:res+=2000;break; + case 4:res+=1500;break; + case 5:res+=700;break; + } + switch (clrbns) + { + case 0:break; + case 1:res+=1500;break; + case 2:res+=2700;break; + case 3:res+=4000;break; + case 4:res+=5500;break; + } + return res; +} +void Options_Writeback() +{ + freopen(".blrrc","w",stdout); + printf(";CBL"); + printf("%c",fpslvl==2?1:0); + printf("%c",tfs?1:0); + printf("%c",VidMode); + printf("%c",diffkey?1:0); + printf("%c%c",bgmvol,sfxvol); + printf("%c%c%c%c",plrspd,plrslospd,clrbns,clrmode); + fclose(stdout); +} +char *getRank() +{ + static char retval[256]; + //sprintf something to retval + if(mode!=2) + { + if(level<=6)sprintf(retval,"Still need more effort!"); + if(level<=3)sprintf(retval,"Try more..."); + if(level==7)sprintf(retval,"You've done it!"); + if(level==-1)sprintf(retval,"Why do you come to Earth?"); + } + else + { + if(asts>900)sprintf(retval,"Contact me immediately!!"); + if(asts<=900)sprintf(retval,"Perfect player."); + if(asts<=600)sprintf(retval,"That's awesome."); + if(asts<=450)sprintf(retval,"Not so bad..."); + if(asts<=120)sprintf(retval,"Are you kidding?"); + } + return retval; +} +static const char* MMStr[]={ + "Start", + "Highscore", + "Options", + "Help", + "About", + "Exit" +}; +static const char* OMStr[]={ + "Fullscreen", + "VSync", + "Clear Range Key", + "Resolution", + "Music Volume", + "SFX Volume", + "Player Preference", + "Save and Exit", + "On", + "Off", + "X", + "Z", + "800x600", + "640x480", + "960x720", + "1024x768", + "1280x960", + "?" +}; +static const char *PPMStr[]={ + "Moving Speed", + "Precise Moving Speed", + "Clear Range Bonus", + "Clear Range Mode", + "Ability Point", + "Back", + "Expand", + "Rotate" +}; +static const char *PMStr[]={ + "Paused...", + "Return to Game", + "Return to Title" +}; +static const char *RTTMStr[]={ + "Really?", + "I've pressed the wrong key...", + "Do return to title!" +}; +static const char *DMStr[]={ + "Continue? You score will be set to minus!", + "Continue!", + "No thanks..." +}; +static const char *CMStr[]={ + "Keep this in your highscore record?", + "Yes", + "No thanks..." +}; +static const char *HSMStr[]={ + "Classic Mode", + "Assessment Mode", + "Free Play Mode", + "Back" +}; +class MainMenu +{ +private: + bool active,onIn,onOut; + int selected; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + xoffset=start;onIn=true;active=true; + selected=0;dyoffset=yoffset=-selected*30; + ConfigureQuad(&UpperGradient,xoffset-140,250,320,100); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,420,320,110); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + if(DBGColor!=0xFF0A0A0A) + { + for(int i=0;i<6;++i)DBGColor=ColorTransfer(DBGColor,0xFF0A0A0A); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + if(onIn) + { + if(fabs(xoffset-650)<hge->Timer_GetDelta()*1600)return xoffset=650,onIn=false,-1; + if(xoffset<650) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,250,320,100); + ConfigureQuad(&LowerGradient,xoffset-140,420,320,110); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>0)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<6-1)++selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)selected=5,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(selected==4?2:1),selected; + return -1; + } + void Render() + { + for(int i=0;i<6;++i) + { + double calcy=i*30+dyoffset+360; + if(calcy>249.9&&calcy<500.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,MMStr[i]); + } + Ribb->RenderEx(xoffset-50,355,0,3,1); + Ribb->RenderEx(xoffset-50,382,0,3,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + } +}mainMenu; +class StartMenu +{ +private: + bool active,onIn,onOut; + double xoffset,yoffset,moffset; + int selected; + hgeQuad LeftGradient,RightGradient,LowerGradient; + hgeSprite *clzk,*azmt,*fpmd,*msel; +public: + bool isActive(){return active;} + void Init_Once() + { + clzk=new hgeSprite(MenuTex,0,0,256,128); + azmt=new hgeSprite(MenuTex,256,0,256,128); + fpmd=new hgeSprite(MenuTex,0,128,256,128); + msel=new hgeSprite(MenuTex,256,128,256,64); + clzk->SetHotSpot(128,64); + azmt->SetHotSpot(128,64); + fpmd->SetHotSpot(128,64); + } + void Init() + { + active=true;onIn=true;yoffset=275; + selected=0;xoffset=-selected*300;moffset=450; + ConfigureQuad(&LowerGradient,0,400+yoffset,800,120); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + ConfigureQuad(&LeftGradient,0,320+yoffset,100,200); + LeftGradient.v[0].col=LeftGradient.v[3].col=SETA(DBGColor,0xFF); + LeftGradient.v[1].col=LeftGradient.v[2].col=SETA(DBGColor,0x00); + ConfigureQuad(&RightGradient,700,320+yoffset,100,200); + RightGradient.v[0].col=RightGradient.v[3].col=SETA(DBGColor,0x00); + RightGradient.v[1].col=RightGradient.v[2].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + LeftGradient.v[0].col=LeftGradient.v[3].col=SETA(DBGColor,0xFF); + LeftGradient.v[1].col=LeftGradient.v[2].col=SETA(DBGColor,0x00); + RightGradient.v[0].col=RightGradient.v[3].col=SETA(DBGColor,0x00); + RightGradient.v[1].col=RightGradient.v[2].col=SETA(DBGColor,0xFF); + if(onIn) + { + bool alldone=true; + if(fabs(yoffset-0)<hge->Timer_GetDelta()*800) + yoffset=0; + else + alldone=false,yoffset-=hge->Timer_GetDelta()*800; + if(fabs(moffset-0)<hge->Timer_GetDelta()*1200) + moffset=0; + else alldone=false,moffset-=hge->Timer_GetDelta()*1200; + if(alldone)onIn=false; + } + if(onOut) + { + bool alldone=true; + if(fabs(yoffset-275)<hge->Timer_GetDelta()*800) + yoffset=275; + else + alldone=false,yoffset+=hge->Timer_GetDelta()*800; + if(fabs(moffset-450)<hge->Timer_GetDelta()*1200) + moffset=450; + else alldone=false,moffset+=hge->Timer_GetDelta()*800; + if(alldone)onOut=active=false; + } + if(hge->Input_GetKeyStateEx(HGEK_LEFT)==HGEKST_HIT&&selected>0)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_RIGHT)==HGEKST_HIT&&selected<3-1)++selected,TriggerSound(0); + if(fabs(xoffset-(-selected*300))<hge->Timer_GetDelta()*1000) + xoffset=-selected*300; + else + { + if(xoffset<-selected*300)xoffset+=hge->Timer_GetDelta()*1000; + if(xoffset>-selected*300)xoffset-=hge->Timer_GetDelta()*1000; + } + ConfigureQuad(&LowerGradient,0,400+yoffset,800,120); + ConfigureQuad(&LeftGradient,0,320+yoffset,100,200); + ConfigureQuad(&RightGradient,700,320+yoffset,100,200); + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)TriggerSound(2); + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(1),selected; + return -1; + } + void Render() + { + clzk->Render(400+xoffset,fabs((xoffset+0))*0.075+400+yoffset); + azmt->Render(700+xoffset,fabs((xoffset+300))*0.075+400+yoffset); + fpmd->Render(1000+xoffset,fabs((xoffset+600))*0.075+400+yoffset); + hge->Gfx_RenderQuad(&LowerGradient); + hge->Gfx_RenderQuad(&LeftGradient); + hge->Gfx_RenderQuad(&RightGradient); + msel->Render(0,moffset+200); + } +}startMenu; +class OptionsMenu +{ +private: + bool active,onIn,onOut,onSwitch,onSwitchi; + int selected; + double xoffset,yoffset,dyoffset,swoffset,moffset; + hgeSprite *Ribb,*optt; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + optt=new hgeSprite(MenuTex,256,192,256,64); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + xoffset=start;onIn=active=true;onSwitch=onSwitchi=false; + selected=0;dyoffset=yoffset=-selected*30;moffset=350; + ConfigureQuad(&UpperGradient,xoffset-140,250,500,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,430,500,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + if(onIn) + { + bool alldone=true; + if(fabs(xoffset-450)<hge->Timer_GetDelta()*1600)xoffset=450;else + { + alldone=false; + if(xoffset<450) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(fabs(moffset-0)<hge->Timer_GetDelta()*1200) + moffset=0; + else alldone=false,moffset-=hge->Timer_GetDelta()*1200; + if(alldone)return onIn=false,-1; + } + if(onOut) + { + bool alldone=true; + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset<850)alldone=false; + if(fabs(moffset-450)<hge->Timer_GetDelta()*1200) + moffset=450; + else alldone=false,moffset+=hge->Timer_GetDelta()*800; + if(alldone)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,250,500,100); + ConfigureQuad(&LowerGradient,xoffset-140,430,500,100); + if(!onSwitch) + { + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>0)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<8-1)++selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)selected=7,TriggerSound(0); + } + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_RIGHT)==HGEKST_HIT&&hge->Input_GetKeyStateEx(HGEK_LEFT)==HGEKST_HIT)return -1; + if(hge->Input_GetKeyStateEx(HGEK_RIGHT)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + { + if(selected==7&&!(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT)) + return -1; + TriggerSound(selected==7?2:0); + if(onSwitch||onSwitchi)return -1; + if(selected<=5) + { + onSwitch=true; + swoffset=100; + } + if(selected==0)tfs=!tfs; + if(selected==1) + { + fpslvl=fpslvl==2?0:2; + if(fpslvl==2)hge->System_SetState(HGE_FPS,HGEFPS_VSYNC); + if(fpslvl==0)hge->System_SetState(HGE_FPS,61); + } + if(selected==2)diffkey=!diffkey; + if(selected==3) + { + ++VidMode; + if(VidMode>4)VidMode=0; + } + if(selected==4) + { + ++bgmvol; + if(bgmvol>15)bgmvol=0; + } + if(selected==5) + { + ++sfxvol; + if(sfxvol>15)sfxvol=0; + } + return selected; + } + if(hge->Input_GetKeyStateEx(HGEK_LEFT)==HGEKST_HIT) + { + if(onSwitch||onSwitchi)return -1; + TriggerSound(0); + if(selected<=5){onSwitchi=true;swoffset=0;} + if(selected==0)tfs=!tfs; + if(selected==1) + { + fpslvl=fpslvl==2?0:2; + if(fpslvl==2)hge->System_SetState(HGE_FPS,HGEFPS_VSYNC); + if(fpslvl==0)hge->System_SetState(HGE_FPS,61); + } + if(selected==2)diffkey=!diffkey; + if(selected==3) + { + --VidMode; + if(VidMode<0)VidMode=4; + } + if(selected==4) + { + --bgmvol; + if(bgmvol<0)bgmvol=15; + } + if(selected==5) + { + --sfxvol; + if(sfxvol<0)sfxvol=15; + } + return selected; + } + return -1; + } + void Render() + { + for(int i=0;i<8;++i) + { + double calcy=i*30+dyoffset+360; + if(calcy>249.9&&calcy<500.1) + { + MenuFont->SetColor(0xFFFFFFFF); + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,OMStr[i]); + if(i==0) + { + if(!(onSwitch||onSwitchi)||selected!=0) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,OMStr[tfs?8:9]); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,OMStr[tfs?9:8]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,OMStr[tfs?8:9]); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,OMStr[tfs?8:9]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,OMStr[tfs?9:8]); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==1) + { + if(!(onSwitch||onSwitchi)||selected!=1) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,OMStr[fpslvl==2?8:9]); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,OMStr[fpslvl==2?9:8]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,OMStr[fpslvl==2?8:9]); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,OMStr[fpslvl==2?8:9]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,OMStr[fpslvl==2?9:8]); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==2) + { + if(!(onSwitch||onSwitchi)||selected!=2) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,OMStr[diffkey?10:11]); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,OMStr[diffkey?11:10]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,OMStr[diffkey?10:11]); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,OMStr[diffkey?10:11]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,OMStr[diffkey?11:10]); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==3) + { + if(!(onSwitch||onSwitchi)||selected!=3) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,VidMode>=0&&VidMode<=4?OMStr[VidMode+12]:OMStr[17]); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,VidMode>=0&&VidMode<=4?OMStr[VidMode==0?16:VidMode+11]:OMStr[17]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,VidMode>=0&&VidMode<=4?OMStr[VidMode+12]:OMStr[17]); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,VidMode>=0&&VidMode<=4?OMStr[VidMode+12]:OMStr[17]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,VidMode>=0&&VidMode<=4?OMStr[VidMode==4?12:VidMode+13]:OMStr[17]); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==4) + { + if(!(onSwitch||onSwitchi)||selected!=4) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,"%d",bgmvol); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",bgmvol==0?15:bgmvol-1); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",bgmvol); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",bgmvol); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",bgmvol==15?0:bgmvol+1); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==5) + { + if(!(onSwitch||onSwitchi)||selected!=5) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,"%d",sfxvol); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",sfxvol==0?15:sfxvol-1); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",sfxvol); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",sfxvol); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",sfxvol==15?0:sfxvol+1); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + } + } + Ribb->RenderEx(xoffset-50,353,0,6,1); + Ribb->RenderEx(xoffset-50,380,0,6,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + optt->Render(300,moffset+300); + } +}optionMenu; +class PlayerPreferenceMenu +{ +private: + bool active,onIn,onOut,onSwitch,onSwitchi; + int selected; + double xoffset,yoffset,dyoffset,swoffset,moffset; + double shaketime,shakeoffset,shakedelay; + hgeSprite *Ribb,*optt; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + optt=new hgeSprite(MenuTex,0,256,256,64); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + xoffset=start;onIn=active=true;onSwitch=onSwitchi=false; + selected=0;dyoffset=yoffset=-selected*30;moffset=350;shaketime=0; + ConfigureQuad(&UpperGradient,xoffset-140,250,520,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,430,520,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + void Shake(){shaketime=0.2;shakeoffset=10;shakedelay=0.033;} + int Update() + { + if(onIn) + { + bool alldone=true; + if(fabs(xoffset-430)<hge->Timer_GetDelta()*1600)xoffset=430;else + { + alldone=false; + if(xoffset<430) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(fabs(moffset-0)<hge->Timer_GetDelta()*1200) + moffset=0; + else alldone=false,moffset-=hge->Timer_GetDelta()*1200; + if(alldone)return onIn=false,-1; + } + if(onOut) + { + bool alldone=true; + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset<850)alldone=false; + if(fabs(moffset-450)<hge->Timer_GetDelta()*1200) + moffset=450; + else alldone=false,moffset+=hge->Timer_GetDelta()*800; + if(alldone)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,250,520,100); + ConfigureQuad(&LowerGradient,xoffset-140,430,520,100); + if(!onSwitch) + { + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>0) + TriggerSound(0),--selected==4?--selected:0; + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<6-1) + TriggerSound(0),++selected==4?++selected:0; + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)TriggerSound(0),selected=5; + } + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_RIGHT)==HGEKST_HIT&&hge->Input_GetKeyStateEx(HGEK_LEFT)==HGEKST_HIT)return -1; + if(hge->Input_GetKeyStateEx(HGEK_RIGHT)==HGEKST_HIT) + { + TriggerSound(1); + if(onSwitch||onSwitchi)return -1; + if(selected<=3) + { + onSwitch=true; + swoffset=100; + } + if(selected==0)++plrspd>5?plrspd=1:0; + if(selected==1)++plrslospd>5?plrslospd=1:0; + if(selected==2)++clrbns>4?clrbns=0:0; + if(selected==3)clrmode=!clrmode; + if(selected<=3)return selected; + } + if(hge->Input_GetKeyStateEx(HGEK_LEFT)==HGEKST_HIT) + { + TriggerSound(1); + if(onSwitch||onSwitchi)return -1; + if(selected<=3){onSwitchi=true;swoffset=0;} + if(selected==0)--plrspd<1?plrspd=5:0; + if(selected==1)--plrslospd<1?plrslospd=5:0; + if(selected==2)--clrbns<0?clrbns=4:0; + if(selected==3)clrmode=!clrmode; + if(selected<=3)return selected; + } + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(selected==5?2:1),selected; + return -1; + } + void Render() + { + for(int i=0;i<6;++i) + { + double calcy=i*30+dyoffset+360; + if(calcy>249.9&&calcy<500.1) + { + MenuFont->SetColor(0xFFFFFFFF); + MenuFont->printf(xoffset-50,calcy,HGETEXT_LEFT,PPMStr[i]); + if(i==0) + { + if(!(onSwitch||onSwitchi)||selected!=0) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,"%d",plrspd); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",plrspd==1?5:plrspd-1); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",plrspd); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",plrspd); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",plrspd==5?1:plrspd+1); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==1) + { + if(!(onSwitch||onSwitchi)||selected!=1) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,"%d",plrslospd); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",plrslospd==1?5:plrslospd-1); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",plrslospd); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",plrslospd); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",plrslospd==5?1:plrslospd+1); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==2) + { + if(!(onSwitch||onSwitchi)||selected!=2) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,"%d",clrbns); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",clrbns==0?4:clrbns-1); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",clrbns); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,"%d",clrbns); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,"%d",clrbns==4?0:clrbns+1); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==3) + { + if(!(onSwitch||onSwitchi)||selected!=3) + MenuFont->printf(xoffset+200,calcy,HGETEXT_LEFT,PPMStr[clrmode?7:6]); + else + { + if(onSwitch) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,PPMStr[clrmode?6:7]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,PPMStr[clrmode?7:6]); + swoffset-=hge->Timer_GetDelta()*400; + if(swoffset<0)swoffset=0,onSwitch=false; + } + if(onSwitchi) + { + MenuFont->SetColor(SETA(0xFFFFFF,255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+100+swoffset,calcy,HGETEXT_LEFT,PPMStr[clrmode?7:6]); + MenuFont->SetColor(SETA(0xFFFFFF,255.0f-255.0f*(swoffset/100.0f))); + MenuFont->printf(xoffset+200+swoffset,calcy,HGETEXT_LEFT,PPMStr[clrmode?6:7]); + swoffset+=hge->Timer_GetDelta()*400; + if(swoffset>100)swoffset=0,onSwitchi=false; + } + } + } + if(i==4) + { + if(shaketime>0) + { + shaketime-=hge->Timer_GetDelta(); + shakedelay-=hge->Timer_GetDelta(); + if(shakedelay<0) + {shakeoffset=-shakeoffset;shakedelay=0.033;} + if(shaketime<=0)shaketime=shakeoffset=0; + } + MenuFont->printf(xoffset+200+shakeoffset,calcy,HGETEXT_LEFT,"%d/10000",AP_Update(plrspd,plrslospd,clrbns)); + } + } + } + Ribb->RenderEx(xoffset-80,355,0,7,1); + Ribb->RenderEx(xoffset-80,382,0,7,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + optt->Render(125,moffset+300); + } +}playerPreferenceMenu; +class PauseMenu +{ +private: + bool active,onIn,onOut; + int selected; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + //special things to do.. + Music_Pause(); + Current_Position=11; + DisableAllTower=DisablePlayer=true; + xoffset=start;onIn=true;active=true; + selected=1;dyoffset=yoffset=-selected*30; + ConfigureQuad(&UpperGradient,xoffset-140,190,320,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,340,320,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){if(!onIn)onOut=true;} + int Update() + { + if(onIn) + { + if(fabs(xoffset-350)<hge->Timer_GetDelta()*1600)return xoffset=350,onIn=false,-1; + if(xoffset<350) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850) + { + active=onOut=false; + if(selected==1)Current_Position=1,DisableAllTower=DisablePlayer=false; + return -1; + } + } + ConfigureQuad(&UpperGradient,xoffset-140,190,320,100); + ConfigureQuad(&LowerGradient,xoffset-140,340,320,110); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>1)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<3-1)++selected,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(1),selected; + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT&&!onIn)return TriggerSound(1),1; + return -1; + } + void Render() + { + for(int i=0;i<3;++i) + { + double calcy=i*30+dyoffset+300; + if(calcy>189.9&&calcy<440.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,PMStr[i]); + } + Ribb->RenderEx(xoffset-50,295,0,4,1); + Ribb->RenderEx(xoffset-50,322,0,4,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + } +}pauseMenu; +class ReturnToTitleMenu +{ +private: + bool active,onIn,onOut; + int selected; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + xoffset=start;onIn=true;active=true; + selected=1;dyoffset=yoffset=-selected*30; + ConfigureQuad(&UpperGradient,xoffset-140,190,320,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,340,320,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + //The background color is likely on a change here... + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + if(onIn) + { + if(fabs(xoffset-350)<hge->Timer_GetDelta()*1600)return xoffset=350,onIn=false,-1; + if(xoffset<350) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,190,320,100); + ConfigureQuad(&LowerGradient,xoffset-140,340,320,110); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>1)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<3-1)++selected,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(1),selected; + return -1; + } + void Render() + { + for(int i=0;i<3;++i) + { + double calcy=i*30+dyoffset+300; + if(calcy>189.9&&calcy<440.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,RTTMStr[i]); + } + Ribb->RenderEx(xoffset-50,295,0,6.5,1); + Ribb->RenderEx(xoffset-50,322,0,6.5,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + } +}returnToTitleMenu; +class DeathMenu +{ +private: + bool active,onIn,onOut; + int selected; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb,*DeathTitle; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + DeathTitle=new hgeSprite(MenuTex,256,256,256,64); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + //Magical things, again... + Current_Position=5;Music_Stop(); + DisableAllTower=true;DisablePlayer=true; + xoffset=start;onIn=true;active=true; + selected=1;dyoffset=yoffset=-selected*30; + ConfigureQuad(&UpperGradient,xoffset-140,290,600,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + //The background color is likely on a change here... + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + if(onIn) + { + if(fabs(xoffset-300)<hge->Timer_GetDelta()*1600)return xoffset=300,onIn=false,-1; + if(xoffset<300) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,290,600,100); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,110); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>1)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<3-1)++selected,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(1),selected; + return -1; + } + void Render() + { + for(int i=0;i<3;++i) + { + double calcy=i*30+dyoffset+400; + if(calcy>289.9&&calcy<540.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,DMStr[i]); + } + Ribb->RenderEx(xoffset-50,395,0,3.75,1); + Ribb->RenderEx(xoffset-50,422,0,3.75,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + MenuFont->printf(xoffset-100,250,HGETEXT_LEFT,"You scored %lld at level %d",score,level); + MenuFont->printf(xoffset-100,280,HGETEXT_LEFT,"Average FPS: %lf\n",averfps); + DeathTitle->Render(xoffset-200,200); + } +}deathMenu; +class CompleteMenu +{ +private: + bool active,onIn,onOut; + int selected; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb,*CompleteTitle; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + CompleteTitle=new hgeSprite(MenuTex,0,320,256,64); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + //Magical things, again... + Current_Position=6;Music_Stop(); + DisableAllTower=true;DisablePlayer=true; + xoffset=start;onIn=true;active=true; + selected=1;dyoffset=yoffset=-selected*30; + ConfigureQuad(&UpperGradient,xoffset-140,390,600,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,540,600,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + //The background color is likely on a change here... + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + if(onIn) + { + if(fabs(xoffset-300)<hge->Timer_GetDelta()*1600)return xoffset=300,onIn=false,-1; + if(xoffset<300) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,390,600,100); + ConfigureQuad(&LowerGradient,xoffset-140,540,600,110); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>1)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<3-1)++selected,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(1),selected; + return -1; + } + void Render() + { + for(int i=0;i<3;++i) + { + double calcy=i*30+dyoffset+500; + if(calcy>389.9&&calcy<640.1) + MenuFont->printf(xoffset-100,calcy,HGETEXT_LEFT,CMStr[i]); + } + Ribb->RenderEx(xoffset-150,495,0,3.75,1); + Ribb->RenderEx(xoffset-150,522,0,3.75,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + if(~CheckHighScore()) + MenuFont->printf(xoffset-100,250,HGETEXT_LEFT,"New Highscore %lld!",score); + else + MenuFont->printf(xoffset-100,250,HGETEXT_LEFT,"Score %lld",score); + MenuFont->printf(xoffset-100,280,HGETEXT_LEFT,"Your Ranking: %s",getRank()); + if(mode==2) + { + MenuFont->printf(xoffset-100,310,HGETEXT_LEFT,"Time elapsed: %.2fs",((int)(asts*100))/100.0); + MenuFont->printf(xoffset-100,340,HGETEXT_LEFT,"Semi-collisions %d",semicoll); + MenuFont->printf(xoffset-100,370,HGETEXT_LEFT,"Average FPS: %.2f",averfps); + } + else + { + if(mode==1) + MenuFont->printf(xoffset-100,310,HGETEXT_LEFT,"Restarts %d",restarts); + else + MenuFont->printf(xoffset-100,310,HGETEXT_LEFT,"Collisions %d",coll); + MenuFont->printf(xoffset-100,340,HGETEXT_LEFT,"Semi-collisions %d",semicoll); + MenuFont->printf(xoffset-100,370,HGETEXT_LEFT,"CLR Usage %d",clrusg); + MenuFont->printf(xoffset-100,400,HGETEXT_LEFT,"Average FPS: %.2f",averfps); + } + CompleteTitle->Render(xoffset-200,200); + } +}completeMenu; +class NewHighScoreGUI +{ +private: + bool active,onIn,onOut,toogleundl; + double xoffset; + void nameins(char a) + { + if (newlen<=14) + newname[newlen++]=a; + } + void namedel() + { + if (newlen>0)newname[--newlen]=0; + } +public: + bool isActive(){return active;} + void Init() + { + Current_Position=7;active=true; + memset(newname,0,sizeof(newname));newlen=0;tbframebrk=0;toogleundl=false; + TipFont->SetColor(0xFFFFFFFF);xoffset=-500;onIn=true;onOut=false; + } + void Leave(){onOut=true;} + void Update() + { + if(onIn) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>0)xoffset=0,onIn=false; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>650)onOut=active=false; + } + int key=hge->Input_GetKey(); + if (key>=0x30&&key<=0x39)nameins('0'+key-0x30); + #ifdef WIN32 + if (key>=0x41&&key<=0x5A) + if (GetKeyState(VK_CAPITAL)&1)nameins('A'+key-0x41);else nameins('a'+key-0x41); + #else + if (key>=0x41&&key<=0x5A) + nameins('A'+key-0x41); + #endif + if (key==HGEK_SPACE)nameins('_'); + if (key==HGEK_BACKSPACE)namedel(); + if (key==HGEK_ENTER) + { + TriggerSound(1); + InsertHighScore();Leave(); + Current_Position=0;mainMenu.Init(-200); + /*switch (mode) + { + case 4:view=1;HSViewGUI_Init();break; + case 1:view=2;HSViewGUI_Init();break; + case 2:view=3;HSViewGUI_Init();break; + case 3:view=4;HSViewGUI_Init();break; + }*/ + } + } + void Render() + { + if (LOWFPS)tbframebrk+=17;else ++tbframebrk; + if (tbframebrk>=500)toogleundl=!toogleundl,tbframebrk=0; + TipFont->printf(200+xoffset,200,HGETEXT_LEFT,"Please Enter Your Honorable Name..."); + if (!toogleundl) + TipFont->printf(200+xoffset,240,HGETEXT_LEFT,"%s",newname); + else + TipFont->printf(200+xoffset,240,HGETEXT_LEFT,"%s_",newname); + } +}newHighScoreGUI; +class HighScoreMenu +{ +private: + bool active,onIn,onOut; + int selected; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb,*HSTitle; + hgeQuad UpperGradient,LowerGradient; +public: + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + HSTitle=new hgeSprite(MenuTex,0,376,256,64); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start) + { + xoffset=start;onIn=true;active=true; + selected=0;dyoffset=yoffset=-selected*30; + ConfigureQuad(&UpperGradient,xoffset-140,290,600,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,100); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + if(onIn) + { + if(fabs(xoffset-500)<hge->Timer_GetDelta()*1600)return xoffset=500,onIn=false,-1; + if(xoffset<500) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,290,600,100); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,110); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>0)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<4-1)++selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)selected=4-1,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(selected==4-1?2:1),selected; + return -1; + } + void Render() + { + for(int i=0;i<4;++i) + { + double calcy=i*30+dyoffset+400; + if(calcy>289.9&&calcy<540.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,HSMStr[i]); + } + Ribb->RenderEx(xoffset-50,395,0,4.5,1); + Ribb->RenderEx(xoffset-50,422,0,4.5,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + HSTitle->Render(xoffset-250,300); + } +}highScoreMenu; +class HighScoreViewMenu +{ +private: + bool active,onIn,onOut; + int selected,view; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb; + hgeQuad UpperGradient,LowerGradient; +public: + int View(){return view;} + int GetViewCount(){return view==0?Ncnt:view==1?Excnt:view==2?FPMcnt:0;} + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start,int _v) + { + xoffset=start;onIn=true;active=true; + selected=1;dyoffset=yoffset=-selected*30;view=_v; + ConfigureQuad(&UpperGradient,xoffset-140,290,600,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,120); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + if(onIn) + { + if(fabs(xoffset-400)<hge->Timer_GetDelta()*1600)return xoffset=400,onIn=false,-1; + if(xoffset<400) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,290,600,100); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,120); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>1)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<7-1)++selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)selected=7-1,TriggerSound(0); + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(selected==7-1?2:1),selected; + return -1; + } + void Render() + { + if(dyoffset+400>289.9) + MenuFont->printf(xoffset,dyoffset+400,HGETEXT_LEFT,"Highscore - %s",HSMStr[view]); +#define WrapCnt \ + (view==0?Ncnt:view==1?Excnt:view==2?FPMcnt:0) +#define WrapRec\ + (view==0?NRec:view==1?ExRec:view==2?FPMRec:FPMRec) + for(unsigned i=1;i<=5;++i) + { + double calcy=i*30+dyoffset+400; + if(calcy>289.9&&calcy<540.1) + { + if(i<=WrapCnt) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,"%u. %s - %lld",i,WrapRec[i].name,WrapRec[i].score); + else MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,"%u. ----------",i); + } + } + double calcy=6*30+dyoffset+400; + if(calcy>289.9&&calcy<540.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,"back"); + Ribb->RenderEx(xoffset-50,395,0,7,1); + Ribb->RenderEx(xoffset-50,422,0,7,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + } +}highScoreViewMenu; +class HighScoreDetailsMenu +{ +private: + bool active,onIn,onOut; + int selected,view,no; + double xoffset,yoffset,dyoffset; + hgeSprite *Ribb,*HSTitle; + hgeQuad UpperGradient,LowerGradient; +public: + int View(){return view;} + bool isActive(){return active;} + void Init_Once() + { + Ribb=new hgeSprite(MenuTex,256,350,64,16); + HSTitle=new hgeSprite(MenuTex,0,448,256,64); + Ribb->SetColor(0xCCFFFFFF); + } + void Init(double start,int _v,int _n) + { + xoffset=start;onIn=true;active=true;no=_n; + selected=0;dyoffset=yoffset=-selected*30;view=_v; + ConfigureQuad(&UpperGradient,xoffset-140,290,600,50); + UpperGradient.v[0].col=UpperGradient.v[1].col=SETA(DBGColor,0xFF); + UpperGradient.v[2].col=UpperGradient.v[3].col=SETA(DBGColor,0x00); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,130); + LowerGradient.v[0].col=LowerGradient.v[1].col=SETA(DBGColor,0x00); + LowerGradient.v[2].col=LowerGradient.v[3].col=SETA(DBGColor,0xFF); + } + void Leave(){onOut=true;} + int Update() + { + if(onIn) + { + if(fabs(xoffset-400)<hge->Timer_GetDelta()*1600)return xoffset=400,onIn=false,-1; + if(xoffset<400) + xoffset+=hge->Timer_GetDelta()*1600; + else + xoffset-=hge->Timer_GetDelta()*1600; + } + if(onOut) + { + xoffset+=hge->Timer_GetDelta()*1600; + if(xoffset>=850)active=onOut=false; + } + ConfigureQuad(&UpperGradient,xoffset-140,290,600,100); + ConfigureQuad(&LowerGradient,xoffset-140,440,600,130); + if(hge->Input_GetKeyStateEx(HGEK_UP)==HGEKST_HIT&&selected>0)--selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_DOWN)==HGEKST_HIT&&selected<(view==1?6:7)-1)++selected,TriggerSound(0); + if(hge->Input_GetKeyStateEx(HGEK_ESCAPE)==HGEKST_HIT)TriggerSound(0),selected=(view==1?6:7)-1; + yoffset=-selected*30; + if(fabs(dyoffset-yoffset)<7)dyoffset=yoffset; + if(dyoffset<yoffset)dyoffset+=hge->Timer_GetDelta()*400; + if(dyoffset>yoffset)dyoffset-=hge->Timer_GetDelta()*400; + if(onIn||onOut)return -1; + if(hge->Input_GetKeyStateEx(HGEK_Z)==HGEKST_HIT||hge->Input_GetKeyStateEx(HGEK_ENTER)==HGEKST_HIT) + return TriggerSound(selected==(view==1?5:7)-1?2:1),selected; + return -1; + } + void Render() + { +#define WrapCnt \ + (view==0?Ncnt:view==1?Excnt:view==2?FPMcnt:0) +#define WrapRec\ + (view==0?NRec:view==1?ExRec:view==2?FPMRec:FPMRec) + if(dyoffset+400>289.9) + MenuFont->printf(xoffset,dyoffset+400,HGETEXT_LEFT,"No. %d of %s",no,HSMStr[view]); + if(view==1) + { + if(dyoffset+430>289.9&&dyoffset+430<540.1) + MenuFont->printf(xoffset,dyoffset+430,HGETEXT_LEFT,"Scored %lld by %s",WrapRec[no].score,WrapRec[no].name); + if(dyoffset+460>289.9&&dyoffset+460<540.1) + MenuFont->printf(xoffset,dyoffset+460,HGETEXT_LEFT,"Time elapsed %.2fs",WrapRec[no].rescol/100.0); + if(dyoffset+490>289.9&&dyoffset+490<540.1) + MenuFont->printf(xoffset,dyoffset+490,HGETEXT_LEFT,"Semi-Collisions %d",WrapRec[no].scoll); + if(dyoffset+520>289.9&&dyoffset+520<540.1) + MenuFont->printf(xoffset,dyoffset+520,HGETEXT_LEFT,"Average FPS %d.%d",WrapRec[no].af_int,WrapRec[no].af_fric); + } + else + { + if(dyoffset+430>289.9&&dyoffset+430<540.1) + MenuFont->printf(xoffset,dyoffset+430,HGETEXT_LEFT,"Scored %lld by %s",WrapRec[no].score,WrapRec[no].name); + if(dyoffset+460>289.9&&dyoffset+460<540.1) + { + if(view==0) + MenuFont->printf(xoffset,dyoffset+460,HGETEXT_LEFT,"Restarts %d",WrapRec[no].rescol); + else + MenuFont->printf(xoffset,dyoffset+460,HGETEXT_LEFT,"Collisions %d",WrapRec[no].rescol); + } + if(dyoffset+490>289.9&&dyoffset+490<540.1) + MenuFont->printf(xoffset,dyoffset+490,HGETEXT_LEFT,"Semi-Collisions %d",WrapRec[no].scoll); + if(dyoffset+520>289.9&&dyoffset+520<540.1) + MenuFont->printf(xoffset,dyoffset+520,HGETEXT_LEFT,"CLR Usage %d",WrapRec[no].clrusg); + if(dyoffset+550>289.9&&dyoffset+550<540.1) + MenuFont->printf(xoffset,dyoffset+550,HGETEXT_LEFT,"Average FPS %d.%d",WrapRec[no].af_int,WrapRec[no].af_fric); + } + double calcy=(view==1?5:6)*30+dyoffset+400; + if(calcy>289.9&&calcy<540.1) + MenuFont->printf(xoffset,calcy,HGETEXT_LEFT,"back"); + Ribb->RenderEx(xoffset-50,395,0,6,1); + Ribb->RenderEx(xoffset-50,422,0,6,1); + hge->Gfx_RenderQuad(&UpperGradient); + hge->Gfx_RenderQuad(&LowerGradient); + HSTitle->Render(xoffset-250,300); + } +}highScoreDetailsMenu; diff --git a/archive/blr2/src/music.h b/archive/blr2/src/music.h new file mode 100644 index 0000000..ef09c41 --- /dev/null +++ b/archive/blr2/src/music.h @@ -0,0 +1,34 @@ +//Chrisoft Bullet Lab Remix HGE -*- C++ -*- +//In Game Music Implementations +//Copyright Chrisoft 2014 +HEFFECT Mus; +HCHANNEL Muc; +int lpst,lped; +//static const char* MUSIC_H_FN="music.h"; + +void Music_Init(const char* file) +{ + Mus=hge->Effect_Load(file); +} +void Music_Play() +{ + Muc=hge->Effect_PlayEx(Mus,bgmvol/15.0,0,1.0,true); +} +void Music_Update() +{ + if (!lpst||!lped)return; + int Mucpos=hge->Channel_GetPos_BySample(Muc); + if (Mucpos>=lped)hge->Channel_SetPos_BySample(Muc,lpst); +} +void Music_Stop() +{ + hge->Channel_Stop(Muc); +} +void Music_Pause() +{ + hge->Channel_Pause(Muc); +} +void Music_Resume() +{ + hge->Channel_Resume(Muc); +} diff --git a/archive/blr2/src/scorec.h b/archive/blr2/src/scorec.h new file mode 100644 index 0000000..abca9c6 --- /dev/null +++ b/archive/blr2/src/scorec.h @@ -0,0 +1,258 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Score Recording Implementations +// Copyright Chrisoft 2014 +//static const char* SCOREC_H_FN="scorec.h"; + +struct TRecord +{ + long long score; + int len,rescol,scoll,clrusg; + int af_int,af_fric; + char name[16]; +}ERec[10],NRec[10],ExRec[10],FPMRec[10]; +unsigned int Ecnt,Ncnt,Excnt,FPMcnt; +unsigned int header,seprt; +char newname[16]; +int newlen,tbframebrk; +unsigned int Getuint() +{ + unsigned int c1,c2,c3,c4,res; + c1=c2=c3=c4=0; + c1=getchar();c2=getchar();c3=getchar();c4=getchar(); + res=(c1<<24)+(c2<<16)+(c3<<8)+c4; + return res; +} +int Getint() +{ + return (int)Getuint(); +} +long long Getll() +{ + long long c1,c2,c3,c4,c5,c6,c7,c8,res; + c1=c2=c3=c4=c5=c6=c7=c8=0; + c1=getchar();c2=getchar();c3=getchar();c4=getchar(); + c5=getchar();c6=getchar();c7=getchar();c8=getchar(); + res=(c1<<56)+(c2<<48)+(c3<<40)+(c4<<32)+(c5<<24)+(c6<<16)+(c7<<8)+c8; + return res; +} +void Putuint(unsigned int a) +{ + unsigned int c1,c2,c3,c4; + c1=a&0xFF000000;c1>>=24;c2=a&0x00FF0000;c2>>=16; + c3=a&0x0000FF00;c3>>=8;c4=a&0x000000FF; + printf("%c%c%c%c",c1,c2,c3,c4); +} +void Putint(int a) +{ + Putuint((unsigned int)a); +} +void Putll(unsigned long long a) +{ + unsigned long long c1,c2,c3,c4,c5,c6,c7,c8; + c1=a&0xFF00000000000000LL;c1>>=56LL; + c2=a&0x00FF000000000000LL;c2>>=48LL; + c3=a&0x0000FF0000000000LL;c3>>=40LL; + c4=a&0x000000FF00000000LL;c4>>=32LL; + c5=a&0x00000000FF000000LL;c5>>=24LL; + c6=a&0x0000000000FF0000LL;c6>>=16LL; + c7=a&0x000000000000FF00LL;c7>>=8LL; + c8=a&0x00000000000000FFLL; + printf("%c%c%c%c%c%c%c%c",(int)c1,(int)c2,(int)c3,(int)c4,(int)c5,(int)c6,(int)c7,(int)c8); +} +TRecord GetTRecord() +{ + TRecord res; + res.len=Getint(); + memset(res.name,0,sizeof(res.name)); + for (int i=0;i<res.len;++i)scanf("%c",&res.name[i]); + res.score=Getll(); + res.rescol=Getint(); + res.scoll=Getint(); + res.clrusg=Getint(); + res.af_int=Getint();res.af_fric=Getint(); + return res; +} +void PutTRecord(TRecord a) +{ + Putint(a.len); + for (int i=0;i<a.len;++i)printf("%c",a.name[i]); + Putll(a.score); + Putint(a.rescol); + Putint(a.scoll); + Putint(a.clrusg); + Putint(a.af_int);Putint(a.af_fric); +} +void Score_Init() +{ + freopen(".blrscore","r",stdin); + header=Getuint(); + if (header!=0x3b424c53)//0x3b424c53=";BLS" + { + fclose(stdin); + Error("Error when loading score file!"); + } + seprt=Getuint(); + if (seprt!=0xd1ffa0c0) + { + fclose(stdin); + Error("Error when loading score file!"); + } + Ecnt=Getuint(); + for (unsigned int i=1;i<=Ecnt;++i)ERec[i]=GetTRecord(); + seprt=Getuint(); + if (seprt!=0xd1ffa0c1) + { + fclose(stdin); + Error("Error when loading score file!"); + } + Ncnt=Getuint(); + for (unsigned int i=1;i<=Ncnt;++i)NRec[i]=GetTRecord(); + seprt=Getuint(); + if (seprt!=0xd1ffa0c2) + { + fclose(stdin); + Error("Error when loading score file!"); + } + Excnt=Getuint(); + for (unsigned int i=1;i<=Excnt;++i)ExRec[i]=GetTRecord(); + seprt=Getuint(); + if (seprt!=0xd1ffa0c3) + { + fclose(stdin); + Error("Error when loading score file!"); + } + FPMcnt=Getuint(); + for (unsigned int i=1;i<=FPMcnt;++i)FPMRec[i]=GetTRecord(); + fclose(stdin); +} +int CheckHighScore() +{ + unsigned i; + switch (mode) + { + case 4: + for (i=1;i<=Ecnt;++i) + if (ERec[i].score<score)break; + if (i==5&&ERec[i].score>score)return -1; + if (Ecnt<5&&ERec[Ecnt].score>score)return Ecnt+1; + return i; + break; + case 1: + for (i=1;i<=Ncnt;++i) + if (NRec[i].score<score)break; + if (i==5&&NRec[i].score>score)return -1; + if (Ncnt<5&&NRec[Ncnt].score>score)return Ncnt+1; + return i; + break; + case 2: + for (i=1;i<=Excnt;++i) + if (ExRec[i].score<score)break; + if (i==5&&ExRec[i].score>score)return -1; + if (Excnt<5&&ExRec[Ncnt].score>score)return Excnt+1; + return i; + break; + case 3: + for (i=1;i<=FPMcnt;++i) + if (FPMRec[i].score<score)break; + if (i==5&&FPMRec[i].score>score)return -1; + if (FPMcnt<5&&FPMRec[Ncnt].score>score)return FPMcnt+1; + return i; + break; + } + return 100; +} +void Score_Write() +{ + freopen(".blrscore","w",stdout); + Putuint(0x3b424c53); + Putuint(0xd1ffa0c0); + Putint(Ecnt); + for (unsigned i=1;i<=Ecnt;++i) + PutTRecord(ERec[i]); + Putuint(0xd1ffa0c1); + Putint(Ncnt); + for (unsigned i=1;i<=Ncnt;++i) + PutTRecord(NRec[i]); + Putuint(0xd1ffa0c2); + Putint(Excnt); + for (unsigned i=1;i<=Excnt;++i) + PutTRecord(ExRec[i]); + Putuint(0xd1ffa0c3); + Putint(FPMcnt); + for (unsigned i=1;i<=FPMcnt;++i) + PutTRecord(FPMRec[i]); + fclose(stdout); +} +void Score_Initailize() +{ + if(access(".blrscore",R_OK)==0)return; + freopen(".blrscore","w",stdout); + Putuint(0x3b424c53); + Putuint(0xd1ffa0c0);Putuint(0); + Putuint(0xd1ffa0c1);Putuint(0); + Putuint(0xd1ffa0c2);Putuint(0); + Putuint(0xd1ffa0c3);Putuint(0); + fclose(stdout); +} +void InsertHighScore() +{ + unsigned pos=CheckHighScore(); + switch (mode) + { + case 4: + //deprecated... + if (pos<=Ecnt) + for (unsigned i=5;i>pos;--i) + ERec[i]=ERec[i-1]; + else ++Ecnt; + if (Ecnt<5)++Ecnt; + ERec[pos].score=score; + ERec[pos].len=newlen; + memcpy(ERec[pos].name,newname,sizeof(newname)); + ERec[pos].clrusg=clrusg; + ERec[pos].rescol=restarts;ERec[pos].scoll=semicoll; + ERec[pos].af_int=(int)averfps; + ERec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10; + break; + case 1: + if (pos<=Ncnt) + for (unsigned i=5;i>pos;--i) + NRec[i]=NRec[i-1]; + if (Ncnt<5)++Ncnt; + NRec[pos].score=score; + NRec[pos].len=newlen; + memcpy(NRec[pos].name,newname,sizeof(newname)); + NRec[pos].clrusg=clrusg; + NRec[pos].rescol=restarts;NRec[pos].scoll=semicoll; + NRec[pos].af_int=(int)averfps; + NRec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10; + break; + case 2: + if (pos<=Excnt) + for (unsigned i=5;i>pos;--i) + ExRec[i]=ExRec[i-1]; + if (Excnt<5)++Excnt; + ExRec[pos].score=score; + ExRec[pos].len=newlen; + memcpy(ExRec[pos].name,newname,sizeof(newname)); + ExRec[pos].clrusg=clrusg; + ExRec[pos].rescol=asts*100;ExRec[pos].scoll=semicoll; + ExRec[pos].af_int=(int)averfps; + ExRec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10; + break; + case 3: + if (pos<=FPMcnt) + for (unsigned i=5;i>pos;--i) + FPMRec[i]=FPMRec[i-1]; + if (FPMcnt<5)++FPMcnt; + FPMRec[pos].score=score; + FPMRec[pos].len=newlen; + memcpy(FPMRec[pos].name,newname,sizeof(newname)); + FPMRec[pos].clrusg=clrusg; + FPMRec[pos].rescol=coll;FPMRec[pos].scoll=semicoll; + FPMRec[pos].af_int=(int)averfps; + FPMRec[pos].af_fric=(int)(averfps*10)%10*10+(int)(averfps*100)%10; + break; + } + Score_Write(); +} diff --git a/archive/blr2/src/scoresystem.h b/archive/blr2/src/scoresystem.h new file mode 100644 index 0000000..c8efc79 --- /dev/null +++ b/archive/blr2/src/scoresystem.h @@ -0,0 +1,158 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Multiplier implementations +// Copyright Chrisoft 2014 +CircleIndicator MultTimer; +hgeFont *MultFnt; +hgeSprite *MB; +int valbrk; +//static const char* SCORESYSTEM_H_FN="scoresystem.h"; + +//Multiplier Indicator + +HangUpText MT[255]; +void NewMT() +{ + int i=0;while (MT[i].Active())++i; + char ttext[10];sprintf(ttext,"x%.2lf",mult); + MT[i].Init("./Resources/charmap.fnt",ttext,1.0f,200,-50); + MT[i].Launch(vector2d(playerpos.x,playerpos.y-25)); +} +void ProcessMT() +{ + for (int i=0;i<=255;++i)if (MT[i].Active())MT[i].Process(hge->Timer_GetDelta()); +} + +//Multiplier +1 +class MultPo +{ +private: + hgeSprite *Mult,*SpwnEfx; + double Lifetime,LifeLim,speed; + vector2d position,direction; + int blinkbrk; + bool Active,blnkshow,followplyr; +public: + bool IsActive(){return Active;} + void Init(double _lt,double _speed,vector2d _pos,vector2d _dir) + { + Lifetime=0;LifeLim=_lt;speed=_speed;position=_pos;direction=_dir; + Mult=new hgeSprite(SprSheet,0,272,48,48);Active=true;blinkbrk=0;blnkshow=true; + Mult->SetHotSpot(24,24);followplyr=false;SpwnEfx=new hgeSprite(SprSheet,48,272,48,48); + SpwnEfx->SetHotSpot(24,24); + } + void Process() + { + if(GetDist(playerpos,position)<=64)followplyr=true; + if(!clrmode) + { + if(clrrange!=0&&GetDist(playerpos,position)<=clrmaxrange)followplyr=true; + } + else + { + if(clrrad-pi/2>1e-7&&GetDist(playerpos,position)<=clrmaxrange)followplyr=true; + } + if(followplyr) + { + direction=ToUnitCircle(playerpos-position); + speed=0.4; + }else Lifetime+=hge->Timer_GetDelta(); + if(GetDist(playerpos,position)<=9) + { + ++mult,NewMT(),Active=false; + delete Mult;delete SpwnEfx;return; + } + if(Lifetime>LifeLim) + { + delete Mult;delete SpwnEfx; + return (void)(Active=false); + } + if(Lifetime<LifeLim*0.03) + { + double siz=(LifeLim*0.03-Lifetime)/(LifeLim*0.03)*3; + SpwnEfx->SetColor(SETA(SpwnEfx->GetColor(),Lifetime/(LifeLim*0.03)*255)); + SpwnEfx->RenderEx(position.x,position.y,0,siz); + } + if(Lifetime>LifeLim*0.8) + { + if (!LOWFPS)++blinkbrk;else blinkbrk+=17; + if (blinkbrk>200)blinkbrk=0,blnkshow=!blnkshow; + if (blnkshow) + Mult->RenderEx(position.x,position.y,0,0.8); + } + else + Mult->RenderEx(position.x,position.y,0,0.8); + if(!followplyr) + { + if (position.x>780||position.x<20)direction.x=-direction.x; + if (position.y>780||position.y<20)direction.y=-direction.y; + } + int times=1;if (LOWFPS)times=17; + for (int i=1;i<=times;++i) + position.x+=direction.x*speed,position.y+=direction.y*speed; + } +}; +MultPo Multpo[255]; +void NewMultpo(vector2d pos=vector2d(-99,-99)) +{ + int i=0;while (Multpo[i].IsActive())++i; + if (pos.x+99<=1e-6&&pos.y+99<=1e-6) + pos.x=re.NextInt(20,770),pos.y=re.NextInt(20,570); + vector2d dir=ToUnitCircle(vector2d(rand()%1000-500,rand()%1000-500)); + Multpo[i].Init(7.5,0.02,pos,dir); +} +void ProcessMultpo() +{ + for (int i=0;i<=255;++i)if(Multpo[i].IsActive())Multpo[i].Process(); +} +//Auto Multipliers + +void Mult_Init() +{ + MultTimer.Init(50,0.95,0xC0,false,SprSheet,TextureRect(151,264,2,8),0x00FF0000); + multbrk=TenSeconds;multbat=mult=1;valbrk=0; + MB=new hgeSprite(MultFnt->GetTexture(),0,235,163,21); + MB->SetHotSpot(81.5,10.5); + memset(Multpo,0,sizeof(Multpo)); +} +double GetHscle() +{ + if (multbrk<=TenSeconds/10.0f*0.2f)return (TenSeconds/10.0f*0.3f-multbrk)/(TenSeconds/10.0f)*10; + if (multbrk<=TenSeconds/10.0f*4.5f)return 1.0f; + return (multbrk-TenSeconds/10.0f*4.15f)/(multbrk-TenSeconds/10.0f)*10; +} +int GetAlpha() +{ + if (multbrk<=TenSeconds/10.0f*0.2f)return (int)(255-255*(TenSeconds/10.0f*0.2f-multbrk)/(TenSeconds/50.0f)); + if (multbrk<=TenSeconds/10.0f*4.5f)return 0xFF; + return (int)(255*(TenSeconds/2-multbrk)/(TenSeconds/10)); +} +void Mult_FrameFunc() +{ + if (Current_Position!=1)return; + ProcessMT();ProcessMultpo(); + --multbrk; + if(!dsmc)lsc+=hge->Timer_GetDelta();else lsc=0; + if(lsc>1&&mult>1.0f)mult-=hge->Timer_GetDelta()/20.0f; + if (multbrk<0) + { + multbrk=ThirtySeconds; + mult+=multbat;lsc=0; + NewMT(); + if (multbat<5)++multbat; + } + if (multbrk<TenSeconds/2) + { + ++valbrk; + if (LOWFPS||valbrk>30) + MultTimer.SetValue((double)multbrk/((double)TenSeconds/2.0f)); + if (valbrk>30)valbrk=0; + MultTimer.Render(playerpos.x+8.4,playerpos.y+8.4); + MB->SetColor(SETA(0x00FFFFFF,0.8*GetAlpha())); + MB->RenderEx(playerpos.x+8.4,playerpos.y-26.4,0,GetHscle(),1.0f); + } +} +void Mult_BatClear() +{ + multbrk=ThirtySeconds; + multbat=1; +} diff --git a/archive/blr2/src/towernbullet.h b/archive/blr2/src/towernbullet.h new file mode 100644 index 0000000..8acf516 --- /dev/null +++ b/archive/blr2/src/towernbullet.h @@ -0,0 +1,2892 @@ +// Chrisoft Bullet Lab Remix HGE -*- C++ -*- +// Towers and Bullets Implementations +// Copyright Chrisoft 2014 +#include "effects.h" +//static const char* TOWERNBULLET_H_FN="towernbullet.h"; + +void RenderAlter(vector2d p,TColors ca,TColors cb,double rot=0,double scl=1) +{ + float x,y,w,h; + bulletspr[ca]->GetTextureRect(&x,&y,&w,&h); + bulletspr[ca]->SetTextureRect(x,y,12,h); + bulletspr[ca]->SetHotSpot(12,12); + bulletspr[ca]->RenderEx(p.x,p.y,rot,scl); + bulletspr[ca]->SetTextureRect(x,y,w,h); + bulletspr[ca]->SetHotSpot(12,12); + + bulletspr[cb]->GetTextureRect(&x,&y,&w,&h); + bulletspr[cb]->SetTextureRect(x,y,12,h); + bulletspr[cb]->SetHotSpot(12,12); + bulletspr[cb]->RenderEx(p.x,p.y,rot+pi,scl); + bulletspr[cb]->SetTextureRect(x,y,w,h); + bulletspr[cb]->SetHotSpot(12,12); +} +int CreateBullet1(double x,double y,double bs,bool eff=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=1; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=x-playerpos.x; + bullet[i].bulletdir.y=y-playerpos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].alterColor=green;bullet[i].alterColor2=COLOR_COUNT; + bullet[i].scollable=true; + bullet[i].scale=1; + if (eff)BulletEffect_Attatch(i); + return i; +} +int CreateBullet2(double x,double y,double bs,double rad,bool eff=false,bool invi=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].addblend=false; + bullet[i].extborder=false; + bullet[i].inv=invi; + bullet[i].bullettype=2; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir=vector2d(cos(rad),sin(rad)); + bullet[i].limpos=vector2d(-999,-999); + bullet[i].bulletspeed=bs; + bullet[i].alterColor=blue; + bullet[i].alterColor2=COLOR_COUNT; + bullet[i].lifetime=0; + bullet[i].whirem=0; + bullet[i].scollable=true; + bullet[i].collable=true; + bullet[i].bulletaccel=bullet[i].limv=0; + bullet[i].scale=1;bullet[i].rot=0; + if (eff)BulletEffect_Attatch(i); + return i; +} +void CreateBullet3(double x,double y,double bs,int dir,bool eff=false) +{ + CreateBullet2(x,y,bs,dir*0.5235987756,eff,false); +} +void CreateBullet4(double x,double y,double bs,int yelbrk=0,bool eff=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=4; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=x-playerpos.x; + bullet[i].bulletdir.y=y-playerpos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].yelbrk=yelbrk; + bullet[i].scollable=true; + bullet[i].scale=1;bullet[i].lifetime=0; + bullet[i].alterColor=yellow;bullet[i].alterColor2=COLOR_COUNT; + if (eff)BulletEffect_Attatch(i); +} +void CreateBullet5(double x,double y,double bs,bool eff=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=5; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=x-playerpos.x; + bullet[i].bulletdir.y=y-playerpos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].alterColor=purple;bullet[i].alterColor2=COLOR_COUNT; + bullet[i].scollable=true; + bullet[i].scale=1; + if (eff)BulletEffect_Attatch(i); +} +int CreateBullet6(double x,double y,double bs,int explo,int exp1=8,int exp2=12,bool eff=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=6; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=re.NextDouble(-1,1); + bullet[i].bulletdir.y=re.NextDouble(-1,1); + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].alterColor=red;bullet[i].alterColor2=COLOR_COUNT; + bullet[i].redattrib=0; + bullet[i].exp1=exp1; + bullet[i].exp2=exp2; + bullet[i].oriexplo=bullet[i].redexplo=explo; + bullet[i].scollable=true; + bullet[i].scale=1; + if (eff)BulletEffect_Attatch(i); + return i; +} +int CreateBullet7(double x,double y,double bs,int explo,bool eff=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=7; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=re.NextDouble(-1,1); + bullet[i].bulletdir.y=re.NextDouble(-1,1); + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].alterColor=white;bullet[i].alterColor2=COLOR_COUNT; + bullet[i].oriexplo=bullet[i].redexplo=explo; + bullet[i].redattrib=0; + bullet[i].whirem=whicnt; + bullet[i].whiskp=0; + bullet[i].scollable=true; + bullet[i].scale=1; + if (eff)BulletEffect_Attatch(i); + return i; +} +int CreateBullet8(double x,double y,double bs,bool eff=false) +{ + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=8; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=x-playerpos.x; + bullet[i].bulletdir.y=y-playerpos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].alterColor=dblue;bullet[i].alterColor2=COLOR_COUNT; + bullet[i].scollable=true; + bullet[i].scale=1; + if (eff)BulletEffect_Attatch(i); + return i; +} +int CreateBullet9(double x,double y,double bs,int explo,int cnt,int brk,bool eff=false) +{ + //This creates bullet9 in random direction and as attrib 0 + //change them if necessary. + ++shots; + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].inv=false; + bullet[i].bullettype=9; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].bulletdir.x=re.NextDouble(-1,1); + bullet[i].bulletdir.y=re.NextDouble(-1,1); + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].oriexplo=bullet[i].redexplo=explo; + bullet[i].redattrib=0; + bullet[i].whicnt=cnt; + bullet[i].yelbrk=brk; + bullet[i].alterColor=orange;bullet[i].alterColor2=COLOR_COUNT; + bullet[i].scollable=true; + bullet[i].scale=1; + if (eff)BulletEffect_Attatch(i); + return i; +} +void CreateBullet255(double x,double y,double bs,int spno=0) +{ + int i=AllocBullet(); + bullet[i].exist=true; + bullet[i].bullettype=255; + bullet[i].bulletpos.x=x; + bullet[i].bulletpos.y=y; + bullet[i].redattrib=spno; + vector2d spos=playerpos+splitData[spno]; + bullet[i].bulletdir.x=x-spos.x; + bullet[i].bulletdir.y=y-spos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + bullet[i].bulletspeed=bs; + bullet[i].exp1=re.NextInt(0,9)?0:1; +} +void All2pnt() +{ + for (int i=1;i<=bulcnt;++i) + { + if(bullet[i].bullettype<200&&bullet[i].exist) + { + CreateBullet255(bullet[i].bulletpos.x,bullet[i].bulletpos.y,10); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + } +} +void ProcessBullet1(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=1)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + BulletEffect_Process(i); + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7)++coll,scminus+=10000,Mult_BatClear(); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } +} +void ProcessBullet2(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=2)return; + if (Current_Position==1)bullet[i].lifetime+=hge->Timer_GetDelta(); + if (!DisablePlayer) + { + //experimental new coor processing code, FPS independent + if (bullet[i].whirem<=0) + { + if (bullet[i].bulletaccel>0&&bullet[i].bulletspeed<bullet[i].limv)bullet[i].bulletspeed+=bullet[i].bulletaccel*(1000.0f/hge->Timer_GetFPS()); + if (bullet[i].bulletaccel<0&&bullet[i].bulletspeed>bullet[i].limv)bullet[i].bulletspeed+=bullet[i].bulletaccel*(1000.0f/hge->Timer_GetFPS()); + } + else + bullet[i].whirem-=1000.0f/hge->Timer_GetFPS(); + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x)/20*(1000.0f/hge->Timer_GetFPS()); + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y)/20*(1000.0f/hge->Timer_GetFPS()); + if(GetDist(bullet[i].bulletpos,bullet[i].limpos)<1) + { + BulletEffect_Death(bullet[i],ColorToDWORD(bullet[i].alterColor)); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=-999; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0;return; + } + } + BulletEffect_Process(i); + if(PlayerSplit) + { + bool rndr=true; + for(int j=0;j<4;++j) + { + double dis=GetDist(bullet[i].bulletpos,playerpos+splitData[j]); + if (bullet[i].bulletpos.x<=-25||bullet[i].bulletpos.x>=825||bullet[i].bulletpos.y<=-25||bullet[i].bulletpos.y>=625) + { + bullet[i].exist=false;rndr=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=-999; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + return; + } + if (bullet[i].scale<1.2&&dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7&&bullet[i].collable) + { + ++coll,scminus+=10000,Mult_BatClear();bullet[i].collable=false;rndr=false; + if(!bullet[i].inv) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + return; + } + else + { + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(playerpos+splitData[j]); + } + } + if(rndr) + { + if(bullet[i].alterColor2==COLOR_COUNT) + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + else + RenderAlter(vector2d(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2),bullet[i].alterColor,bullet[i].alterColor2,bullet[i].rot,0.6*bullet[i].scale), + Current_Position==1?bullet[i].rot+=(i&1?1:-1)*(1000/hge->Timer_GetFPS())*pi/1000:0; + } + } + else + { + double dis=GetDist(bullet[i].bulletpos,playerpos); + if ((!bullet[i].extborder&&(bullet[i].bulletpos.x<=-25||bullet[i].bulletpos.x>=825||bullet[i].bulletpos.y<=-25||bullet[i].bulletpos.y>=625))|| + (bullet[i].extborder&&(bullet[i].bulletpos.x<=-225||bullet[i].bulletpos.x>=1025||bullet[i].bulletpos.y<=-225||bullet[i].bulletpos.y>=825))) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=-999; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + return; + } + if (bullet[i].scale<1.2&&dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7&&bullet[i].collable) + { + ++coll,scminus+=10000,Mult_BatClear();bullet[i].collable=false; + if(!bullet[i].inv) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + return; + } + else + { + if(bullet[i].alterColor2==COLOR_COUNT) + { + if(bullet[i].addblend)bulletspr[bullet[i].alterColor]->SetBlendMode(0); + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + if(bullet[i].addblend)bulletspr[bullet[i].alterColor]->SetBlendMode(2); + } + else + RenderAlter(vector2d(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2),bullet[i].alterColor,bullet[i].alterColor2,bullet[i].rot,0.6*bullet[i].scale), + Current_Position==1?bullet[i].rot+=(i&1?1:-1)*(1000/hge->Timer_GetFPS())*pi/1000:0; + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } + } +} +//There is no need for ProcessBullet3() because they are in fact bullet2 +void ProcessBullet4(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=4)return; + if (Current_Position==1)bullet[i].lifetime+=hge->Timer_GetDelta(); + if (!DisablePlayer) + { + if (LOWFPS) + bullet[i].whirem+=17; + else + ++bullet[i].whirem; + if ((yelattrib&&bullet[i].whirem>=bullet[i].yelbrk)||!yelattrib) + { + bullet[i].whirem=0; + bullet[i].bulletdir.x=bullet[i].bulletpos.x-playerpos.x; + bullet[i].bulletdir.y=bullet[i].bulletpos.y-playerpos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + } + if (LOWFPS) + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + BulletEffect_Process(i); + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7)++coll,scminus+=10000,Mult_BatClear(); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } +} +void ProcessBullet5(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=5)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + BulletEffect_Process(i); + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7)playerspeed*=0.9,playerslospeed*=0.9; + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + } +} +void ProcessBullet6(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=6)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + if (!LOWFPS) + { + if (bullet[i].redattrib==0) + --bullet[i].redexplo; + else + bullet[i].redexplo-=2; + } + else + { + if (bullet[i].redattrib==0) + bullet[i].redexplo-=17; + else + bullet[i].redexplo-=34; + } + if (bullet[i].redexplo<=0&&!DisableAllTower) + { + if (bullet[i].redattrib==0) + { + for (int j=1;j<=bullet[i].exp1;++j) + { + int pnt=CreateBullet6(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,bullet[i].oriexplo,bullet[i].exp1,bullet[i].exp2,bullet[i].scale>1.5?true:false); + bullet[pnt].setdir(2*pi/(double)bullet[i].exp1*j); + bullet[pnt].redattrib=1; + } + } + else + { + for (int j=1;j<=bullet[i].exp2;++j) + CreateBullet2(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,2*pi/(double)bullet[i].exp2*j+clockrot,bullet[i].scale>1.5?true:false); + clockrot+=deltarot; + deltarot+=0.004363322313; + } + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + BulletEffect_Process(i); + if(PlayerSplit) + { + bool rndr=true; + for(int j=0;j<4;++j) + { + double dis=GetDist(bullet[i].bulletpos,playerpos+splitData[j]); + if (bullet[i].bulletpos.x<=-25||bullet[i].bulletpos.x>=825||bullet[i].bulletpos.y<=-25||bullet[i].bulletpos.y>=625) + { + bullet[i].exist=false;rndr=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=-999; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + return; + } + if (bullet[i].scale<1.2&&dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7&&bullet[i].collable) + { + ++coll,scminus+=10000,Mult_BatClear();bullet[i].collable=false;rndr=false; + if(!bullet[i].inv) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + return; + } + else + { + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(playerpos+splitData[j]); + } + } + if(rndr) + { + if(bullet[i].alterColor2==COLOR_COUNT) + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + else + RenderAlter(vector2d(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2),bullet[i].alterColor,bullet[i].alterColor2,bullet[i].rot,0.6*bullet[i].scale), + Current_Position==1?bullet[i].rot+=(i&1?1:-1)*(1000/hge->Timer_GetFPS())*pi/1000:0; + } + } + else + { + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (bullet[i].bulletpos.x<=-25||bullet[i].bulletpos.x>=825||bullet[i].bulletpos.y<=-25||bullet[i].bulletpos.y>=625) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=-999; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + return; + } + if (bullet[i].scale<1.2&&dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7&&bullet[i].collable) + { + ++coll,scminus+=10000,Mult_BatClear();bullet[i].collable=false; + if(!bullet[i].inv) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + return; + } + else + { + if(bullet[i].alterColor2==COLOR_COUNT) + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + else + RenderAlter(vector2d(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2),bullet[i].alterColor,bullet[i].alterColor2,bullet[i].rot,0.6*bullet[i].scale), + Current_Position==1?bullet[i].rot+=(i&1?1:-1)*(1000/hge->Timer_GetFPS())*pi/1000:0; + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } + } +} +void ProcessBullet7(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=7)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bsscale*bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + if (!LOWFPS) + { + if (bullet[i].redattrib==0) + --bullet[i].redexplo; + else + bullet[i].redexplo-=2; + } + else + { + if (bullet[i].redattrib==0) + bullet[i].redexplo-=17; + else + bullet[i].redexplo-=34; + } + if (bullet[i].redexplo<=0&&!DisableAllTower) + { + if (bullet[i].redattrib==0) + { + int pnt=CreateBullet7(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,bullet[i].oriexplo,bullet[i].scale>1.5?true:false); + + bullet[pnt].bulletdir.x=0; + bullet[pnt].bulletdir.y=0; + bullet[pnt].dist=1; + bullet[pnt].redattrib=1; + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + if (!LOWFPS) + ++bullet[i].whiskp; + else + bullet[i].whiskp+=17; + if (bullet[i].whiskp>50) + { + for (int j=1;j<=whrcnt;++j) + { + int pnt=CreateBullet2(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,j*2.0f*pi/(double)whrcnt+whirot,bullet[i].scale>1.5?true:false); + if(level==6&&part==1) + { + bullet[pnt].limv=8; + bullet[pnt].bulletaccel=0.005; + bullet[pnt].bulletspeed=0; + } + if (level==6&&part>=2&&part<=11&&(j&1)) + { + bullet[pnt].limv=5; + bullet[pnt].bulletaccel=0.005; + bullet[pnt].bulletspeed=0; + bullet[pnt].redir(playerpos); + bullet[pnt].bulletdir.Rotate((j>>1&1?1:-1)*pi/72); + } + } + whirot+=dwhirot; + dwhirot+=0.004363322313; + bullet[i].whiskp=0; + --bullet[i].whirem; + } + if (bullet[i].whirem<=0) + { + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + } + } + BulletEffect_Process(i); + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7)++coll,scminus+=10000,Mult_BatClear(); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } +} +void ProcessBullet8(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=8)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + BulletEffect_Process(i); + if(bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + int cnt=re.NextInt(2,5);if (Dis8ref)cnt=0; + if(PlayerSplit)cnt=re.NextInt(0,2); + if(bullet[i].redattrib) + { + if(re.NextInt(0,3))//more possibility to reflect + { + if(bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800)bullet[i].bulletdir.x=-bullet[i].bulletdir.x; + if(bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600)bullet[i].bulletdir.y=-bullet[i].bulletdir.y; + } + else//vanish or reflect?... + { + cnt=4-4*(frameleft/(double)(AMinute*1.5)); + for (int ii=1;ii<=cnt;++ii) + CreateBullet2(bullet[i].bulletpos.x,bullet[i].bulletpos.y,2,re.NextDouble(-pi,pi)); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + return; + } + } + else + { + for (int ii=1;ii<=cnt;++ii) + { + int pnt=CreateBullet2(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,re.NextDouble(-pi,pi)); + if (t8special) + { + bullet[pnt].alterColor=(TColors)(re.NextInt(0,7)); + bullet[pnt].alterColor2=(TColors)(re.NextInt(0,7)); + if(re.NextInt(0,3)==3)bullet[pnt].redir(vector2d(400,300)); + if(re.NextInt(0,1))++ii; + } + } + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + return; + } + } + if(PlayerSplit) + { + for(int j=0;j<4;++j) + { + double dis=GetDist(bullet[i].bulletpos,playerpos+splitData[j]); + if (dis<=6) + { + if (dis<=6){if(clrrange<1e-5&&clrrad-pi/2<1e-7)++coll,scminus+=10000,Mult_BatClear();} + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(playerpos+splitData[j]); + } + } + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + } + else + { + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (dis<=6) + { + if (dis<=6){if(clrrange<1e-5&&clrrad-pi/2<1e-7)++coll,scminus+=10000,Mult_BatClear();} + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0;return; + } + else + { + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } + } +} +void ProcessBullet9(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=9)return; + if (!DisablePlayer) + { + if (LOWFPS) + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + if (bullet[i].redattrib==0) + { + bullet[i].redexplo-=17; + if (bullet[i].redexplo<=0) + { + for (int ii=0;ii<bullet[i].whicnt;++ii) + { + int pnt=CreateBullet9(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,0,0,bullet[i].yelbrk); + bullet[pnt].setdir(2*pi/(double)bullet[i].whicnt*ii); + bullet[pnt].redattrib=1; + } + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + } + if (bullet[i].redattrib==1) + { + bullet[i].yelbrk-=17; + if (bullet[i].yelbrk<=0) + { + bullet[i].redir(playerpos); + bullet[i].redattrib=2; + } + } + } + else + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + if (bullet[i].redattrib==0) + { + --bullet[i].redexplo; + if (bullet[i].redexplo<=0) + { + for (int ii=0;ii<bullet[i].whicnt;++ii) + { + int pnt=CreateBullet9(bullet[i].bulletpos.x,bullet[i].bulletpos.y,bullet[i].bulletspeed,0,0,bullet[i].yelbrk); + bullet[pnt].setdir(2*pi/(double)bullet[i].whicnt*ii); + bullet[pnt].redattrib=1; + } + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + } + if (bullet[i].redattrib==1) + { + --bullet[i].yelbrk; + if (bullet[i].yelbrk<=0) + { + bullet[i].redir(playerpos); + bullet[i].redattrib=2; + } + } + } + } + BulletEffect_Process(i); + double dis=GetDist(bullet[i].bulletpos,playerpos); + if (dis<=6||bullet[i].bulletpos.x<=-100||bullet[i].bulletpos.x>=900||bullet[i].bulletpos.y<=-100||bullet[i].bulletpos.y>=700) + { + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7)++coll,scminus+=10000,Mult_BatClear(); + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + bulletspr[bullet[i].alterColor]->RenderEx(bullet[i].bulletpos.x+7.2,bullet[i].bulletpos.y+7.2,0,0.6*bullet[i].scale,0); + if (dis<=16&&bullet[i].scollable)++semicoll,++dsmc,bullet[i].scollable=false,SCEffect_Attatch(); + } +} +void ProcessBullet255(int i) +{ + if (!bullet[i].exist||bullet[i].bullettype!=255)return; + if (!DisablePlayer) + { + bullet[i].bulletspeed=10; + vector2d spos=playerpos+splitData[bullet[i].redattrib]; + bullet[i].bulletdir.x=bullet[i].bulletpos.x-spos.x; + bullet[i].bulletdir.y=bullet[i].bulletpos.y-spos.y; + bullet[i].dist=bullet[i].bulletdir.x*bullet[i].bulletdir.x+bullet[i].bulletdir.y*bullet[i].bulletdir.y; + bullet[i].dist=sqrt(bullet[i].dist); + if (LOWFPS) + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20*17; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20*17; + } + else + { + bullet[i].bulletpos.x-=bullet[i].bulletspeed*(bullet[i].bulletdir.x/bullet[i].dist)/20; + bullet[i].bulletpos.y-=bullet[i].bulletspeed*(bullet[i].bulletdir.y/bullet[i].dist)/20; + } + } + double dis=GetDist(bullet[i].bulletpos,playerpos+splitData[bullet[i].redattrib]); + if (dis<=6||bullet[i].bulletpos.x<=-10||bullet[i].bulletpos.x>=800||bullet[i].bulletpos.y<=-10||bullet[i].bulletpos.y>=600) + { + if(bullet[i].exp1)score+=mult*100;else mult+=0.01; + bullet[i].exist=false; + bullet[i].bulletpos.x=bullet[i].bulletpos.y=0; + bullet[i].bulletdir.x=bullet[i].bulletdir.y=0; + bullet[i].dist=0; + bullet[i].bullettype=0; + } + else + { + if(bullet[i].exp1) + { + bulletspr[green]->SetColor(0x40FFFFFF); + bulletspr[green]->SetBlendMode(BLEND_ALPHAADD); + bulletspr[green]->RenderEx(bullet[i].bulletpos.x+6,bullet[i].bulletpos.y+6,0,0.5,0); + bulletspr[green]->SetBlendMode(BLEND_ALPHABLEND); + bulletspr[green]->SetColor(0x80FFFFFF); + } + else + { + bulletspr[grey]->SetColor(0x20FFFFFF); + bulletspr[grey]->SetBlendMode(BLEND_ALPHAADD); + bulletspr[grey]->RenderEx(bullet[i].bulletpos.x+6,bullet[i].bulletpos.y+6,0,0.5,0); + bulletspr[grey]->SetBlendMode(BLEND_ALPHABLEND); + } + } +} +int CreateTower1(double x,double y,int timer,double bs,double offset=0,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=1; + tower[i].bulletspeed=bs; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + tower[i].offset=offset; + return i; +} +int CreateTower2(double x,double y,int timer,double bs,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)return i; + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=2; + tower[i].bulletspeed=bs; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +int CreateTower3(double x,double y,int timer,double bs,int t3t,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)return i; + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=3; + tower[i].bulletspeed=bs; + tower[i].t3t=t3t; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +int CreateTower3_fixeddir(double x,double y,int timer,double bs,double rad,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero)return i; + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=3; + tower[i].bulletspeed=bs; + tower[i].offset=rad;tower[i].t3t=999; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +int CreateTower4(double x,double y,int timer,double bs,int yelbrk=0,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=4; + tower[i].bulletspeed=bs; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].yelbrk=yelbrk; + tower[i].effect=eff; + return i; +} +int CreateTower5(double x,double y,int timer,double bs,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=5; + tower[i].bulletspeed=bs; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +int CreateTower6(double x,double y,int timer,double bs,int redexplo,int exp1=8,int exp2=12,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=6; + tower[i].bulletspeed=bs; + tower[i].redexplo=redexplo; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].exp1=exp1;tower[i].exp2=exp2; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +int CreateTower7(double x,double y,int timer,double bs,int redexplo,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=7; + tower[i].bulletspeed=bs; + tower[i].redexplo=redexplo; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].whicnt=whicnt; + tower[i].effect=eff; + return i; +} +int CreateTower8(double x,double y,int timer,double bs,int timer2,int scnt,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=8; + tower[i].bulletspeed=bs; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towertimer2=tower[i].curtimer2=timer2; + tower[i].shotcount=tower[i].curshotcount=scnt; + tower[i].dblstate=false; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +int CreateTower9(double x,double y,int timer,double bs,int explo,int cnt,int brk,bool eff=false) +{ + int i; + if (towcnt==0) + towcnt=i=1; + else + { + for (i=1;i<=towcnt;++i) + { + if (!tower[i].exist)break; + if (abs(tower[i].towerpos.x-x)<=zero&&abs(tower[i].towerpos.y-y)<=zero) + { + return i; + } + } + if (i>towcnt) + towcnt=i; + } + tower[i].exist=true; + tower[i].towertype=9; + tower[i].bulletspeed=bs; + tower[i].redexplo=explo; + tower[i].whicnt=cnt; + tower[i].yelbrk=brk; + tower[i].towertimer=tower[i].curtimer=timer; + tower[i].towerpos.x=x,tower[i].towerpos.y=y; + tower[i].RendColor=0x80FFFFFF; + tower[i].effect=eff; + return i; +} +void ProcessTower1() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=1)continue; + towerspr[green]->SetColor(tower[i].RendColor); + towerspr[green]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + if (fabs(tower[i].offset)>1e-7) + { + double trad=atan2l(tower[i].towerpos.y-playerpos.y,tower[i].towerpos.x-playerpos.x)+tower[i].offset; + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,trad,tower[i].effect); + } + else + CreateBullet1(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].effect); + } + } +} +void ProcessTower2() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=2)continue; + towerspr[blue]->SetColor(tower[i].RendColor); + towerspr[blue]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + for (int j=1;j<=12;++j) + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,j*0.5236+clockrot,tower[i].effect); + clockrot+=deltarot; + deltarot+=deltadelta; + } + } +} +void ProcessTower3() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=3)continue; + towerspr[blue]->SetColor(tower[i].RendColor); + towerspr[blue]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + if (tower[i].t3t==999) + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].offset,tower[i].effect); + if (tower[i].t3t==0) + for (int j=1;j<=12;++j) + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,j,tower[i].effect); + if (tower[i].t3t==1) + { + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,12,tower[i].effect); + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,3,tower[i].effect); + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,6,tower[i].effect); + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,9,tower[i].effect); + } + if (tower[i].t3t==4) + { + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*3/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*5/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*7/4.0f,tower[i].effect); + } + if (tower[i].t3t==5) + { + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*3/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*5/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*7/4.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,0,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi/2.0f,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi,tower[i].effect); + CreateBullet2(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,pi*3/2.0f,tower[i].effect); + } + if (tower[i].t3t==2) + { + if (re.NextInt(0,1)) + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,12,tower[i].effect); + else + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,6,tower[i].effect); + } + if (tower[i].t3t==3) + { + if (re.NextInt(0,1)) + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,3,tower[i].effect); + else + CreateBullet3(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,9,tower[i].effect); + } + } + } +} +void ProcessTower4() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=4)continue; + towerspr[yellow]->SetColor(tower[i].RendColor); + towerspr[yellow]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + CreateBullet4(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].yelbrk,tower[i].effect); + } + } +} +void ProcessTower5() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=5)continue; + towerspr[purple]->SetColor(tower[i].RendColor); + towerspr[purple]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + CreateBullet5(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].effect); + } + } +} +void ProcessTower6() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=6)continue; + towerspr[red]->SetColor(tower[i].RendColor); + towerspr[red]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + CreateBullet6(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].redexplo,tower[i].exp1,tower[i].exp2,tower[i].effect); + } + } +} +void ProcessTower7() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=7)continue; + towerspr[white]->SetColor(tower[i].RendColor); + towerspr[white]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + CreateBullet7(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].redexplo,tower[i].effect); + } + } +} +void ProcessTower8() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=8)continue; + towerspr[dblue]->SetColor(tower[i].RendColor); + towerspr[dblue]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (!tower[i].dblstate) + { + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + tower[i].dblstate=true; + tower[i].curtimer2=tower[i].towertimer2; + tower[i].curshotcount=tower[i].shotcount; + if (!Dis8ref&&!t8special)BTarg.TargShow(); + if (!Dis8ref)BTarg.targpos=playerpos; + if (PlayerSplit) + { + int r=0; + for(int i=1;i<4;++i) + if(GetDist(playerpos+splitData[r],vector2d(400,300))> + GetDist(playerpos+splitData[i],vector2d(400,300)))r=i; + BTarg.targpos=playerpos+splitData[r]; + } + } + } + else + { + if (LOWFPS) + tower[i].curtimer2-=17; + else + --tower[i].curtimer2; + if (tower[i].curtimer2<=0) + { + if (tower[i].curshotcount<=0) + { + tower[i].curtimer=tower[i].towertimer; + tower[i].dblstate=false; + tower[i].curtimer2=tower[i].towertimer2; + tower[i].curshotcount=tower[i].shotcount; + if (!Dis8ref)BTarg.TargHide(); + continue; + } + if (!t8special) + { + int pnt=CreateBullet8(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].effect); + if(level==-1&&part==21)bullet[pnt].redattrib=1;else bullet[pnt].redattrib=0; + if (Dis8ref) + { + if (tower[i].towerpos.y<300) + bullet[pnt].setdir(-pi/2);else bullet[pnt].setdir(pi/2); + } + else bullet[pnt].redir(BTarg.targpos); + } + else + { + for(int j=0;j<5;++j) + { + int pnt=CreateBullet8(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].effect); + bullet[pnt].alterColor=white; + bullet[pnt].redir(BTarg.targpos); + bullet[pnt].bulletdir.Rotate(j*2*pi/5); + } + } + tower[i].curtimer2=tower[i].towertimer2; + --tower[i].curshotcount; + } + } + } +} +void ProcessTower9() +{ + for (int i=1;i<=towcnt;++i) + { + if (!tower[i].exist||tower[i].towertype!=9)continue; + towerspr[orange]->SetColor(tower[i].RendColor); + towerspr[orange]->RenderEx(tower[i].towerpos.x+7.2,tower[i].towerpos.y+7.2,0,0.545); + if (DisableAllTower)continue; + if (LOWFPS) + tower[i].curtimer-=17; + else + --tower[i].curtimer; + if (tower[i].curtimer<=0) + { + tower[i].curtimer=tower[i].towertimer; + CreateBullet9(tower[i].towerpos.x,tower[i].towerpos.y,tower[i].bulletspeed,tower[i].redexplo,tower[i].whicnt,tower[i].yelbrk,tower[i].effect); + } + } +} +//Laser Implementation +int Lasercnt; +class Laser +{ +private: + hgeDistortionMesh *graphic; + int Res; + vector2d data1[MaxRes],data2[MaxRes]; + double GetDist() + { + double res=99999.9999f,tres; + static vector2d correction=vector2d(8.4,8.4); + for (int i=0;i<Res-1;++i) + { + vector2d sa,sb; + sa=data1[i]+RenCtr;sb=data1[i+1]+RenCtr; + tres=GetDistSeg(sa,sb,playerpos+correction); + sa=data2[i]+RenCtr;sb=data2[i+1]+RenCtr; + if(GetDistSeg(sa,sb,playerpos+correction)<tres) + tres=GetDistSeg(sa,sb,playerpos+correction); + if (tres<res)res=tres; + } + return res; + } +public: + bool EnableColl; + vector2d RenCtr; + int collbrk,scollbrk; + void SetRes(int _Res){Res=_Res;} + void Render() + { + graphic->Render(RenCtr.x,RenCtr.y); + } + void Init(int _Res=0) + { + graphic=new hgeDistortionMesh(MaxRes,2); + graphic->Clear(0x00000000); + collbrk=scollbrk=0; + Res=_Res; + EnableColl=false; + } + void SetTexture(HTEXTURE Texture,double x=0.0f,double y=0.0f,double w=0.0f,double h=0.0f) + { + graphic->SetTexture(Texture); + if (x||y||w||h)graphic->SetTextureRect(x,y,w,h); + } + void Setdata(int x,vector2d pa,vector2d pb,DWORD color) + { + data1[x]=pa;data2[x]=pb; + graphic->SetDisplacement(x,0,data1[x].x,data1[x].y,HGEDISP_TOPLEFT); + graphic->SetDisplacement(x,1,data2[x].x,data2[x].y,HGEDISP_TOPLEFT); + graphic->SetColor(x,0,color);graphic->SetColor(x,1,color); + } + bool InsPoint(vector2d pa,vector2d pb,DWORD color) + { + if (Res==MaxRes)return false; + data1[++Res-1]=pa;data2[Res-1]=pb; + graphic->SetDisplacement(Res-1,0,data1[Res].x,data1[Res].y,HGEDISP_TOPLEFT); + graphic->SetDisplacement(Res-1,1,data2[Res].x,data2[Res].y,HGEDISP_TOPLEFT); + graphic->SetColor(Res-1,0,color);graphic->SetColor(Res-1,1,color); + return true; + } + void RemoveLastPoint(DWORD color) + { + for (int i=2;i<=Res;++i) + { + data1[i-1]=data1[i]; + data2[i-1]=data2[i]; + graphic->SetDisplacement(i-1,0,data1[i-1].x,data1[i-1].y,HGEDISP_TOPLEFT); + graphic->SetDisplacement(i-1,1,data2[i-1].x,data2[i-1].y,HGEDISP_TOPLEFT); + graphic->SetColor(i-1,0,color);graphic->SetColor(i-1,1,color); + } + graphic->SetDisplacement(Res-1,0,data1[Res].x,data1[Res].y,HGEDISP_TOPLEFT); + graphic->SetDisplacement(Res-1,1,data2[Res].x,data2[Res].y,HGEDISP_TOPLEFT); + graphic->SetColor(Res-1,0,color);graphic->SetColor(Res-1,1,color); + --Res; + } + void Process() + { + Render(); + if (EnableColl) + { + if (GetDist()<3.0f&&clrrange<1e-5&&clrrad-pi/2<1e-7) + { + if (!LOWFPS)++collbrk;else collbrk+=17; + if (collbrk>200) + ++coll,scminus+=10000,collbrk=0,Mult_BatClear(); + } + } + if (GetDist()<9.0f) + { + if (!LOWFPS)++scollbrk;else scollbrk+=17; + if (scollbrk>200) + ++semicoll,scollbrk=0,++dsmc,SCEffect_Attatch(); + } + + } +}laser[200]; +void ProcessLaser() +{ + //Well, I only cares rendering and collision checking.. + //Change laser data in the level code. + for (int i=1;i<=Lasercnt;++i)laser[i].Process(); +} +//Special bullet creation and processing code for some level... +void CreateBullet2(Bullet &Tar,double x,double y,double bs,double rad,bool eff=false) +{ + Tar.exist=true; + Tar.bullettype=2; + Tar.bulletpos.x=x; + Tar.bulletpos.y=y; + Tar.bulletdir.x=cos(rad); + Tar.bulletdir.y=sin(rad); + Tar.bulletspeed=bs; + Tar.alterColor=blue; + Tar.scale=1; + Tar.scollable=true; + Tar.bulletaccel=0; +} +void ProcessBullet2(Bullet &xbul,bool colchk=true) +{ + if (!xbul.exist||xbul.bullettype!=2)return; + if (!xbul.dist)xbul.dist=1; + if (xbul.bulletaccel>0&&xbul.bulletspeed<xbul.limv)xbul.bulletspeed+=xbul.bulletaccel*(1000.0f/hge->Timer_GetFPS()); + if (xbul.bulletaccel<0&&xbul.bulletspeed>xbul.limv)xbul.bulletspeed+=xbul.bulletaccel*(1000.0f/hge->Timer_GetFPS()); + xbul.bulletpos.x-=xbul.bulletspeed*(xbul.bulletdir.x/xbul.dist)/20*(1000.0f/hge->Timer_GetFPS()); + xbul.bulletpos.y-=xbul.bulletspeed*(xbul.bulletdir.y/xbul.dist)/20*(1000.0f/hge->Timer_GetFPS()); + double dis=GetDist(xbul.bulletpos,playerpos); + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7&&colchk&&xbul.collable) + { + ++coll,scminus+=10000,Mult_BatClear();xbul.collable=false; + return; + } + if (dis<=16&&xbul.scollable)++semicoll,++dsmc,xbul.scollable=false,SCEffect_Attatch(); + if (colchk)bulletspr[xbul.alterColor]->RenderEx(xbul.bulletpos.x+7.2,xbul.bulletpos.y+7.2,0,0.6*xbul.scale); +} +//"Noname" +class Noname01dotpas +{ +private: + Laser untitledlas; + Bullet untitledbul; + double x,y,range1,range2; + double r1lim,r2lim; + bool las,reverse,done; + int PMod,pos,boomlim; + DWORD color; +public: + bool Exist() + { + return (fabs(y)>1e-6); + } + void Init(int x,int pmd,double _r1lim,double _r2lim,int _boomlim,DWORD _color) + { + untitledlas.Init(); + this->x=x,this->y=2;color=_color; + CreateBullet2(untitledbul,x,2,0,3*pi/2); + untitledbul.bulletaccel=0.0005; + untitledbul.limv=2;untitledbul.collable=true; + las=false; + reverse=false; + done=false; + PMod=pmd; + r1lim=_r1lim;r2lim=_r2lim;boomlim=_boomlim; + if (re.NextInt(0,100)>boomlim) + pos=re.NextInt(0,600); + else + pos=999; + untitledlas.SetTexture(SprSheet,0,264,248,8); + } + void noname2pnt() + { + if(!las) + CreateBullet255(untitledbul.bulletpos.x,untitledbul.bulletpos.y,10); + else + { + for (int i=0;i<60;++i) + { + double trad=(i/60.0f)*pi*2; + vector2d a; + if (!(i%PMod)) + { + a.x=cos(trad)*range2;a.y=sin(trad)*range2; + } + else + { + a.x=cos(trad)*range1;a.y=sin(trad)*range1; + } + a=a+untitledbul.bulletpos; + CreateBullet255(a.x,a.y,10); + } + } + } + void Process() + { + if (!las) + ProcessBullet2(untitledbul),x=untitledbul.bulletpos.x,y=untitledbul.bulletpos.y; + else + untitledlas.EnableColl=true, + untitledlas.Process(); + if (!untitledbul.exist)y=-1; + if (y>pos&&!done&&!las) + { + las=true; + range1=range2=2; + for (int i=0;i<60;++i) + { + double trad=(i/60.0f)*pi*2; + vector2d a,b; + a.x=cos(trad)*range1;a.y=sin(trad)*range1; + b.x=cos(trad)*(range1-10);b.y=sin(trad)*(range1-10); + untitledlas.InsPoint(a,b,color); + } + int i=60; + double trad=1.0f/60*pi*2; + vector2d a,b; + if (!(i%PMod)) + { + a.x=cos(trad)*range2;a.y=sin(trad)*range2; + b.x=cos(trad)*(range2-10);b.y=sin(trad)*(range2-10); + } + else + { + a.x=cos(trad)*range1;a.y=sin(trad)*range1; + b.x=cos(trad)*(range1-10);b.y=sin(trad)*(range1-10); + } + for (int i=60;i<MaxRes;++i)untitledlas.InsPoint(a,b,color); + }else + if (las) + { + untitledlas.RenCtr=vector2d(x+7.2,y+7.2); + untitledlas.Render();untitledlas.EnableColl=true; + untitledlas.Process(); + if (!reverse) + { + if (range1<r1lim)range1+=0.2*(1000.0/hge->Timer_GetFPS()),range2=range1; + if (range1>=r1lim&&range2<r2lim)range2+=0.1*(1000.0/hge->Timer_GetFPS()); + if (range2>=r2lim)reverse=true; + } + else + { + if (range2>=r1lim)range2-=0.1*(1000.0/hge->Timer_GetFPS());else range1-=0.2*(1000.0/hge->Timer_GetFPS()),range2=range1; + if (range1<=2)las=false,done=true; + } + for (int i=0;i<60;++i) + { + double trad=(i/60.0f)*pi*2; + vector2d a,b; + if (!(i%PMod)) + { + a.x=cos(trad)*range2;a.y=sin(trad)*range2; + b.x=cos(trad)*(range2-10);b.y=sin(trad)*(range2-10); + } + else + { + a.x=cos(trad)*range1;a.y=sin(trad)*range1; + b.x=cos(trad)*(range1-10);b.y=sin(trad)*(range1-10); + } + untitledlas.Setdata(i,a,b,color); + } + int i=60; + double trad=pi*2; + vector2d a,b; + if (!(i%PMod)) + { + a.x=cos(trad)*range2;a.y=sin(trad)*range2; + b.x=cos(trad)*(range2-10);b.y=sin(trad)*(range2-10); + } + else + { + a.x=cos(trad)*range1;a.y=sin(trad)*range1; + b.x=cos(trad)*(range1-10);b.y=sin(trad)*(range1-10); + } + for (int i=60;i<MaxRes;++i) + untitledlas.Setdata(60,a,b,color); + } + } +}noname[1000]; +//"CTarg" +class SimpleBullet +{ +public: + TColors aC,aC2; + vector2d bulletpos; + int scollable,lastcoll; + double rot; + bool Update_SimpBul() + { + if (lastcoll) + { + ++lastcoll; + if (LOWFPS)lastcoll+=16; + } + if (scollable) + { + ++scollable; + if (LOWFPS)scollable+=16; + } + if (lastcoll>=200)lastcoll=0; + if (scollable>=200)scollable=0; + if (aC2==COLOR_COUNT)bulletspr[aC]->RenderEx(bulletpos.x+7.2,bulletpos.y+7.2,0,0.6,0);//blink hack + else RenderAlter(vector2d(bulletpos.x+7.2,bulletpos.y+7.2),aC,aC2,rot,0.6); + double dis=GetDist(bulletpos,playerpos); + if (dis<=6&&clrrange<1e-5&&clrrad-pi/2<1e-7&&!lastcoll) + { + ++coll,scminus+=10000;lastcoll=1;Mult_BatClear(); + return true;//Collision + } + else + { + if (dis<=16&&!scollable)++semicoll,++dsmc,scollable=1,SCEffect_Attatch(); + return false; + } + } +}; +class TCTarg +{ +private: + Target Targ; + SimpleBullet CircBul[37]; + int BulLim,bul; + double radian,range; + double Ubrk,Ulim; +public: + void Init(int _BulLim,double _InitRange,double _Ulim) + { + Targ.Init(-0.01,playerpos); + Targ.TargShow(); + BulLim=_BulLim; + Ulim=_Ulim; + bul=BulLim; + radian=0; + range=_InitRange; + for (int i=1;i<=BulLim;++i) + { + CircBul[i].bulletpos=vector2d(3+Targ.targpos.x+range*sin(radian-i*(2*pi/BulLim)), + 3+Targ.targpos.y-range*cos(radian-i*(2*pi/BulLim))); + CircBul[i].aC=blue;CircBul[i].aC2=COLOR_COUNT;CircBul[i].rot=0; + CircBul[i].scollable=0; + } + } + double GetRange() + { + return range; + } + void SetRange(double _range) + { + range=_range; + } + void Update() + { + Targ.TargRender(); + if (LOWFPS)radian+=17*60*pi/50000.0f;else radian+=60*pi/50000.0f; + Ubrk+=hge->Timer_GetDelta(); + hgeColorRGB tcol; + tcol.a=tcol.r=1; + tcol.b=tcol.g=Ubrk>Ulim?0.0f:(Ulim-Ubrk)/Ulim; + Targ.targspr->SetColor(tcol.GetHWColor()); + if (Ubrk>Ulim) + { + Targ.TargFollowPlayer(); + if (GetDist(Targ.targpos,playerpos)<4.0f)Ubrk=0.0f; + } + for (int i=1;i<=bul;++i) + { + CircBul[i].bulletpos=vector2d(3+Targ.targpos.x+range*sin(radian-i*(2*pi/BulLim))-6, + 3+Targ.targpos.y-range*cos(radian-i*(2*pi/BulLim))-6); + CircBul[i].Update_SimpBul(); + } + } +}; +TCTarg CTarg; +#undef rad1 +#undef rad2 +class TROF +{ +public: + int Bul[64]; + double rad1,rad2,drad,srad,dtrad,dtrad2; + double range,drange,dtrange,cdtrange; + int stage,cnt,ccnt,delay,cf; + double elasp; + void init() + { + stage=0;rad1=rad2=srad;elasp=0.0f;ccnt=0; + for (int i=0;i<cnt;++i)Bul[i]=CreateBullet8(400,300,0,false),bullet[Bul[i]].setdir(srad),bullet[Bul[i]].scale=0.01,bullet[Bul[i]].inv=true; + bullet[Bul[0]].bulletspeed=2;bullet[Bul[0]].scale=1; + } + void stage0() + { + elasp+=hge->Timer_GetDelta(); + if ((int)(elasp/0.15f)>ccnt&&ccnt<cnt-1) + { + ccnt=(int)(elasp/0.2f); + if (ccnt==1)dtrange=GetDist(bullet[Bul[0]].bulletpos,bullet[Bul[1]].bulletpos); + bullet[Bul[ccnt]].bulletspeed=2;bullet[Bul[ccnt]].scale=1; + } + if (elasp>2) + { + stage=1;NewMultpo(vector2d(400,300)); + drange=GetDist(bullet[Bul[ccnt-1]].bulletpos,vector2d(400,300)); + dtrad=(drad-srad);while (dtrad>pi/6.0f)dtrad-=pi/6.0f;dtrad/=delay; + dtrad2=(2*pi-drad+srad);while (dtrad2>pi/6.0f)dtrad2-=pi/6.0f;dtrad2/=delay; + for (int i=0;i<cnt;++i)bullet[Bul[i]].bulletspeed=0; + cf=0; + } + } + void stage1() + { + cf+=(LOWFPS?17:1); + rad1=srad+dtrad*cf;rad2=srad-dtrad2*cf; + for (int i=0;i<cnt;++i) + if (bullet[Bul[i]].bullettype==8) + { + if (i&1) + bullet[Bul[i]].bulletpos=vector2d(400+(drange+(cnt-i)*dtrange)*cos(rad1-pi),300+(drange+(cnt-i)*dtrange)*sin(rad1-pi)); + else + bullet[Bul[i]].bulletpos=vector2d(400+(drange+(cnt-i)*dtrange)*cos(rad2-pi),300+(drange+(cnt-i)*dtrange)*sin(rad2-pi)); + } + if (cf>delay) + { + cf=delay; + rad1=srad+dtrad*cf;rad2=srad-dtrad2*cf; + for (int i=0;i<cnt;++i) + if (bullet[Bul[i]].bullettype==8) + { + if (i&1) + bullet[Bul[i]].bulletpos=vector2d(400+(drange+(cnt-i)*dtrange)*cos(rad1-pi),300+(drange+(cnt-i)*dtrange)*sin(rad1-pi)); + else + bullet[Bul[i]].bulletpos=vector2d(400+(drange+(cnt-i)*dtrange)*cos(rad2-pi),300+(drange+(cnt-i)*dtrange)*sin(rad2-pi)); + bullet[Bul[i]].bulletspeed=2,bullet[Bul[i]].redir(vector2d(400,300)), + bullet[Bul[i]].bulletdir=vector2d(-bullet[Bul[i]].bulletdir.x,-bullet[Bul[i]].bulletdir.y); + bullet[Bul[i]].inv=false; + } + stage=2; + } + } + void stage2(){} + void update() + { + switch(stage) + { + case 0:stage0();break; + case 1:stage1();break; + case 2:stage2();break; + } + } +}; +class BCircle +{ +private: + SimpleBullet Bullets[360]; + int BCnt; + double radian,range,DT,drad; + vector2d Centre; +public: + void Init(double _irange,double _drad,int _Cnt,vector2d _Centre,TColors _Col=blue,TColors _Col2=COLOR_COUNT) + { + range=_irange; + BCnt=_Cnt; + radian=0; + DT=0.0f; + drad=_drad; + Centre=_Centre; + for (int i=1;i<=BCnt;++i) + { + Bullets[i].bulletpos=vector2d(3+Centre.x+range*sin(radian-i*(2*pi/BCnt))-6, + 3+Centre.y-range*cos(radian-i*(2*pi/BCnt))-6); + Bullets[i].aC=_Col;Bullets[i].aC2=_Col2; + Bullets[i].rot=0; + } + } + double GetRange(){return range;} + void SetRange(double _range){range=_range;} + void SetDT(double _DT){DT=_DT;} + double GetDT(){return DT;} + double GetRad(){return radian;} + void circ2pnt() + { + for(int i=1;i<=BCnt;++i) + CreateBullet255(Bullets[i].bulletpos.x,Bullets[i].bulletpos.y,10); + } + void Update() + { + DT+=hge->Timer_GetDelta(); + if (LOWFPS)radian+=17*drad;else radian+=drad; + for (int i=1;i<=BCnt;++i) + { + Bullets[i].bulletpos=vector2d(3+Centre.x+range*sin(radian-i*(2*pi/BCnt))-6, + 3+Centre.y-range*cos(radian-i*(2*pi/BCnt))-6); + Bullets[i].rot+=(LOWFPS?17:1)*pi/1000; + Bullets[i].Update_SimpBul(); + } + } +}; +class BulletSine +{ +private: + Bullet headb; + vector2d a,b,lastgenerated; + int generated[400]; + int gencnt; + bool OutOfBound() + { + if (headb.bulletpos.x<=-25||headb.bulletpos.x>=825||headb.bulletpos.y<=-25||headb.bulletpos.y>=625) + return true;return false; + } +public: + bool active; + void Init(vector2d _a,vector2d _b) + { + a=_a;b=_b;lastgenerated=_a; + CreateBullet2(headb,a.x,a.y,6,0); + headb.redir(b); + active=true;memset(generated,0,sizeof(generated)); + gencnt=0; + } + void Update() + { + if (GetDist(lastgenerated,headb.bulletpos)>4.0f) + { + ++gencnt; + double rad=(gencnt&1)?(gencnt+1)/2*pi/18.0f:-gencnt/2*pi/18.0f; + generated[gencnt]=CreateBullet2(headb.bulletpos.x,headb.bulletpos.y,0,rad,true); + bullet[generated[gencnt]].inv=true; + lastgenerated=headb.bulletpos; + } + if (OutOfBound()) + { + active=false; + for (int i=1;i<=gencnt;++i) + if (generated[i]) + bullet[generated[i]].bulletaccel=0.005,bullet[generated[i]].limv=2, + bullet[generated[i]].inv=false,bullet[generated[i]].collable=true; + memset(generated,0,sizeof(generated)); + } + ProcessBullet2(headb); + } +}; +class WOP +{ +private: + int trail[200]; + double brk,blim,rad,k,ml; + vector2d a,b; + Bullet hbul; + bool OutOfBound() + { + if (hbul.bulletpos.x<=-25||hbul.bulletpos.x>=825||hbul.bulletpos.y<=-25||hbul.bulletpos.y>=625) + { + for (int i=0;i<200;++i)if (trail[i])return false; + return true; + }return false; + } +public: + bool active; + void Init(vector2d _a,vector2d _b,double _ml,double _bl) + { + a=_a,b=_b,ml=_ml,blim=_bl;rad=0; + if (fabs(b.x-a.x)<1e-6)return;k=(b.y-a.y)/(b.x-a.x); + CreateBullet2(hbul,a.x,a.y,7,0);hbul.redir(b); + active=true;memset(trail,0,sizeof(trail)); + } + void Update() + { + if (Current_Position!=1)return; + ProcessBullet2(hbul,false); + brk+=hge->Timer_GetDelta(); + if (brk>blim) + { + brk=0; + for (int i=0;i<200;++i) + { + if (trail[i]) + if (bullet[trail[i]].lifetime>ml)BulletEffect_Death(bullet[trail[i]],0x8000CCFF),bullet[trail[i]].exist=false,trail[i]=0; + } + rad+=pi/16.0f; + vector2d uv=ToUnitCircle(vector2d(1,-k));uv.Swap(); + int pnt=0;while (trail[pnt])++pnt; + trail[pnt]=CreateBullet2(hbul.bulletpos.x+uv.x*50*sin(rad),hbul.bulletpos.y+uv.y*50*sin(rad),0,0,true); + pnt=0;while (trail[pnt])++pnt; + trail[pnt]=CreateBullet2(hbul.bulletpos.x-uv.x*50*sin(rad),hbul.bulletpos.y-uv.y*50*sin(rad),0,0,true); + } + if (OutOfBound())active=false; + } +}; +class BTail +{ +//devide the screen into a 16*12 matrix, put random colored bullets, arranged +//in the shape of the snake, on to it. +//^Maybe this description is too bad to understand. See the code. +//Partly based on class WOP +private: + class Pile + { + private: + int pb[200]; + int matrixx,matrixy,progress,cnt; + double brk;TColors color; + public: + int getProgress(){return progress;} + void create(int _x,int _y,TColors _col) + { + matrixx=_x;matrixy=_y;color=_col; + progress=1;cnt=0; + } + void kill() + { + for(int i=0;i<cnt;++i) + { + if(pb[i]) + { + if(bullet[pb[i]].bullettype==2) + { + bullet[pb[i]].exist=false;pb[i]=0; + } + } + } + } + void update() + { + if(!progress)return; + if(progress<10) + { + brk+=hge->Timer_GetDelta(); + if(brk>0.03) + { + brk=0;if(progress++>5)return (void)(progress=10); + for(int i=0;i<10;++i) + { + vector2d ran=vector2d(re.NextDouble(0,50)+matrixx*50,re.NextDouble(0,50)+matrixy*50); + pb[cnt++]=CreateBullet2(ran.x,ran.y,0,0,true); + bullet[pb[cnt-1]].alterColor=color; + } + } + } + else + { + brk+=hge->Timer_GetDelta(); + if(brk>0.03) + { + bool alldone=true; + for(int i=0;i<cnt;++i) + { + if(pb[i]) + { + if(bullet[pb[i]].bullettype==2&&bullet[pb[i]].lifetime>1) + { + BulletEffect_Death(bullet[pb[i]],ColorToDWORD(color)); + bullet[pb[i]].exist=false;pb[i]=0; + } + else alldone=false; + } + } + if(alldone)progress=0; + } + } + } + }; + Pile piles[30]; + bool tactive; + int listx[30],listy[30],cnt; + TColors pcolor;double tlifetime; + bool check(int x,int y) + { + if(x<0||x>15)return false; + if(y<0||y>12)return false; + for(int i=0;i<cnt;++i) + if(x==listx[i]&&y==listy[i])return false; + return true; + } +public: + bool isActive(){return tactive;} + void Create() + { + pcolor=(TColors)re.NextInt(0,7);tactive=true; + cnt=0;memset(listx,0,sizeof(listx)); + memset(listy,0,sizeof(listy));tlifetime=0; + listx[cnt++]=re.NextInt(0,15);listy[cnt-1]=re.NextInt(0,11); + piles[cnt-1].create(listx[cnt-1],listy[cnt-1],pcolor); + } + void Update() + { + tlifetime+=hge->Timer_GetDelta(); + if(tlifetime>15) + { + tactive=false; + for(int i=0;i<30;++i) + if(piles[i].getProgress())piles[i].kill(); + } + if(piles[cnt-1].getProgress()==10) + { + int dlx[4],dly[4],dcnt=0; + if(check(listx[cnt-1]+1,listy[cnt-1])) + dlx[dcnt]=listx[cnt-1]+1,dly[dcnt++]=listy[cnt-1]; + if(check(listx[cnt-1]-1,listy[cnt-1])) + dlx[dcnt]=listx[cnt-1]-1,dly[dcnt++]=listy[cnt-1]; + if(check(listx[cnt-1],listy[cnt-1]+1)) + dlx[dcnt]=listx[cnt-1],dly[dcnt++]=listy[cnt-1]+1; + if(check(listx[cnt-1],listy[cnt-1]-1)) + dlx[dcnt]=listx[cnt-1],dly[dcnt++]=listy[cnt-1]-1; + if(dcnt&&cnt<30) + { + int rd=re.NextInt(0,dcnt-1); + listx[cnt++]=dlx[rd];listy[cnt-1]=dly[rd]; + piles[cnt-1].create(listx[cnt-1],listy[cnt-1],pcolor); + } + } + bool none=true; + for(int i=0;i<30;++i) + if(piles[i].getProgress())none=false,piles[i].update(); + if(none)tactive=false; + } +}; +class SimpleThing +{ +private: + vector2d center; + int step,cnt; + double rad,dly,lr,ra; + SimpleBullet b[500]; + double r[500],mr[500]; + bool create,rot; +public: + void Init(vector2d _ctr) + { + center=_ctr;step=cnt=dly=lr=ra=0; + create=true;rot=false; + } + void Update(bool rv) + { + dly+=hge->Timer_GetDelta(); + if(dly>0.2&&create) + { + dly=0; + for(int i=0;i<10;++i) + { + b[cnt].bulletpos=center; + b[cnt].aC=blue;b[cnt].aC2=COLOR_COUNT; + r[cnt/10]=0;mr[cnt/10]=(lr+=2); + if (lr>620)create=false; + ++cnt; + } + } + bool all=!create; + if(!rot) + for(int i=0;i<cnt;++i) + { + b[i].bulletpos=vector2d(center.x+r[i/10]*cos(i/10*pi/12+pi/5*(i%10)),center.y+r[i/10]*sin(i/10*pi/12+pi/5*(i%10))); + if(r[i/10]<mr[i/10])r[i/10]+=(LOWFPS?17:1)*0.01,all=false; + else r[i/10]=mr[i/10]; + b[i].Update_SimpBul(); + } + if(all||rot) + { + rot=true; + rv?rad+=(LOWFPS?17:1)*ra:rad-=(LOWFPS?17:1)*ra; + if(ra<pi/7200)ra+=(LOWFPS?17:1)*pi/630000000.0f; + for(int i=0;i<cnt;++i) + { + b[i].bulletpos=vector2d(center.x+r[i/10]*cos(i/10*pi/12+rad+pi/5*(i%10)),center.y+r[i/10]*sin(i/10*pi/12+rad+pi/5*(i%10))); + b[i].Update_SimpBul(); + } + } + } + void toPoint() + { + for(int i=0;i<cnt;++i) + CreateBullet255(b[i].bulletpos.x,b[i].bulletpos.y,10); + } +}; +class diffCreator +{ +protected: + bool active; + double range; + int cnt; + vector2d center; + int C; + int target[200]; + vector2d created[200]; +private: + TColors rbGetColor(int a) + { + switch (a) + { + case 2:return orange; + case 3:return yellow; + case 4:return green; + case 5:return blue; + case 6:return dblue; + case 7:return purple; + default:return circle; + } + } + bool test(vector2d a) + { + for(int i=0;i<cnt;++i) + if(GetDist(a,created[i])<12)return false; + return true; + } +public: + void init(vector2d _ctr) + { + active=true; + cnt=0;range=0; + center=_ctr; + C=CreateBullet2(center.x,center.y,0,0,true); + bullet[C].alterColor=red; + } + bool isActive(){return active;} + void update() + { + range+=hge->Timer_GetDelta()*400; + vector2d a;bool all=true; + for(a=vector2d(center.x-15,center.y);a.x>-25;a.x-=15) + if(GetDist(a,center)<=range) + { + if(test(a)) + target[cnt++]=CreateBullet2(a.x,a.y,0,0,true), + created[cnt-1]=vector2d(a.x,a.y), + bullet[target[cnt-1]].inv=true, + bullet[target[cnt-1]].alterColor=red; + } + else all=false; + for(a=vector2d(center.x+15,center.y);a.x<825;a.x+=15) + if(GetDist(a,center)<=range) + { + if(test(a)) + target[cnt++]=CreateBullet2(a.x,a.y,0,pi,true), + created[cnt-1]=vector2d(a.x,a.y), + bullet[target[cnt-1]].inv=true, + bullet[target[cnt-1]].alterColor=red; + } + else all=false; + for(a=vector2d(center.x,center.y-15);a.y>-25;a.y-=15) + if(GetDist(a,center)<=range) + { + if(test(a)) + target[cnt++]=CreateBullet2(a.x,a.y,0,pi/2,true), + created[cnt-1]=vector2d(a.x,a.y), + bullet[target[cnt-1]].inv=true, + bullet[target[cnt-1]].alterColor=red; + } + else all=false; + for(a=vector2d(center.x,center.y+15);a.y<625;a.y+=15) + if(GetDist(a,center)<=range) + { + if(test(a)) + target[cnt++]=CreateBullet2(a.x,a.y,0,-pi/2,true), + created[cnt-1]=vector2d(a.x,a.y), + bullet[target[cnt-1]].inv=true, + bullet[target[cnt-1]].alterColor=red; + } + else all=false; + a=center; +#define _bat \ + bullet[target[cnt-1]].redir(center),\ + created[cnt-1]=bullet[target[cnt-1]].bulletpos,\ + bullet[target[cnt-1]].bulletdir.x=-bullet[target[cnt-1]].bulletdir.x,\ + bullet[target[cnt-1]].bulletdir.y=-bullet[target[cnt-1]].bulletdir.y,\ + bullet[target[cnt-1]].inv=true,\ + bullet[target[cnt-1]].alterColor=rbGetColor(i+j); + for(int i=1;i<=6;++i) + for(int j=1;j<=7-i;++j) + if(GetDist(vector2d(a.x+i*15,a.y+j*15),center)<=range){ + if(test(vector2d(a.x+i*15,a.y+j*15))) + target[cnt++]=CreateBullet2(a.x+i*15,a.y+j*15,0,0,true),_bat;} + else all=false; + for(int i=1;i<=6;++i) + for(int j=1;j<=7-i;++j) + if(GetDist(vector2d(a.x-i*15,a.y+j*15),center)<=range){ + if(test(vector2d(a.x-i*15,a.y+j*15))) + target[cnt++]=CreateBullet2(a.x-i*15,a.y+j*15,0,0,true),_bat;} + else all=false; + for(int i=1;i<=6;++i) + for(int j=1;j<=7-i;++j) + if(GetDist(vector2d(a.x+i*15,a.y-j*15),center)<=range){ + if(test(vector2d(a.x+i*15,a.y-j*15))) + target[cnt++]=CreateBullet2(a.x+i*15,a.y-j*15,0,0,true),_bat;} + else all=false; + for(int i=1;i<=6;++i) + for(int j=1;j<=7-i;++j) + if(GetDist(vector2d(a.x-i*15,a.y-j*15),center)<=range){ + if(test(vector2d(a.x-i*15,a.y-j*15))) + target[cnt++]=CreateBullet2(a.x-i*15,a.y-j*15,0,0,true),_bat;} + else all=false; +#undef _bat + if(all) + { + BulletEffect_Death(bullet[C],0x80FF3333); + bullet[C].exist=false; + for(int i=0;i<cnt;++i) + { + bullet[target[i]].bulletspeed=-0.5; + bullet[target[i]].bulletaccel=0.0005; + bullet[target[i]].limv=3; + bullet[target[i]].inv=false; + bullet[target[i]].collable=true; + } + active=false; + } + }; +}; +class RTV +{ +private: + int mode,cnt,stage,spnr,dcorr; + bool active;TColors col; + double drad,rad,brk; + int targ[600]; +public: + bool isActive(){return active;} + void Init(int _mode,double _drad,int _spnr,TColors _c,int _dcorr) + { + mode=_mode;drad=_drad;rad=0;spnr=_spnr; + brk=0;active=true;cnt=0;stage=0;col=_c; + memset(targ,0,sizeof(targ));dcorr=_dcorr; + } + void Update() + { + switch(mode) + { + case 1: + { + brk+=hge->Timer_GetDelta(); + bool dchk=(stage==1); + for(int i=0;i<cnt;++i) + { + if(bullet[targ[i]].bulletspeed>1&&GetDist(vector2d(400,300),bullet[targ[i]].bulletpos)>=200) + bullet[targ[i]].bulletspeed=0; + if(bullet[targ[i]].bulletspeed>1)dchk=false; + } + if(dchk) + { + for(int i=0;i<cnt;++i) + { + double rad=atan2(bullet[targ[i]].bulletdir.y,bullet[targ[i]].bulletdir.x); + int cc=(int)(rad/drad); + if((cc/6+dcorr)&1) + bullet[targ[i]].bulletaccel=0.005, + bullet[targ[i]].limv=3; + else + bullet[targ[i]].bulletaccel=-0.005, + bullet[targ[i]].limv=-3; + } + return(void)(active=false); + } + if(stage==0) + { + if(brk>0.05) + { + brk=0;rad+=drad; + if(fabs(rad)>2*pi/spnr+pi/180)return(void)(stage=1); + for(int i=0;i<spnr;++i) + { + targ[cnt]=CreateBullet2(400,300,2,rad+i*2*pi/spnr), + bullet[targ[cnt]].inv=true, + bullet[targ[cnt++]].alterColor=col; + } + } + } + } + break; + case 2: + { + brk+=hge->Timer_GetDelta(); + bool dchk=(stage==1); + for(int i=0;i<cnt;++i) + { + if(bullet[targ[i]].bulletspeed>1&&GetDist(vector2d(400,300),bullet[targ[i]].bulletpos)>=200) + bullet[targ[i]].bulletspeed=0; + if(bullet[targ[i]].bulletspeed>1)dchk=false; + } + if(dchk) + { + if(re.NextInt(0,1)) + for(int i=0;i<cnt;++i) + bullet[targ[i]].bulletaccel=-0.005, + bullet[targ[i]].limv=-3; + else + for(int i=0;i<cnt;++i) + bullet[targ[i]].bulletaccel=0.005, + bullet[targ[i]].limv=3; + return(void)(active=false); + } + if(stage==0) + { + if(brk>0.05) + { + brk=0;rad+=drad; + if(fabs(rad)>2*pi/spnr+pi/180)return(void)(stage=1); + for(int i=0;i<spnr;++i) + { + targ[cnt]=CreateBullet2(400,300,2,rad+i*2*pi/spnr), + bullet[targ[cnt]].inv=true; + bullet[targ[cnt++]].alterColor=col; + } + } + } + } + break; + case 3: + { + brk+=hge->Timer_GetDelta(); + if(brk>0.05) + { + brk=0;rad+=drad; + if(fabs(rad)>2*pi/spnr+pi/180)return(void)(active=false); + for(int i=0;i<spnr;++i) + { + targ[cnt]=CreateBullet2(400,300,2,rad+i*2*pi/spnr); + bullet[targ[cnt]].inv=true; + bullet[targ[cnt++]].alterColor=col; + targ[cnt]=CreateBullet2(400,300,2,-rad+i*2*pi/spnr); + bullet[targ[cnt]].inv=true; + bullet[targ[cnt++]].alterColor=col; + } + } + } + break; + } + } +}; +bool achromab,achromaB[100]; +class achromaGroup +{ +private: + class achromaBullet:public SimpleBullet + { + private: + bool active; + double spd,acc,lim; + public: + bool isActive(){return active;} + void achromaInit(vector2d pos,TColors initcol,double _lim) + { + bulletpos=pos;spd=0;acc=0.0005;lim=_lim;rot=0; + lastcoll=0;aC=initcol;aC2=COLOR_COUNT; + active=true; + } + void Reverse() + { + spd=0; + if(aC==green)aC=red; + else if(aC==red)aC=green; + } + void achromaUpdate() + { + if(aC==red)lastcoll=1;//ignore coll for red. + bulletpos.y+=spd*(1000.0f/hge->Timer_GetFPS()); + if(spd+acc*(1000.0f/hge->Timer_GetFPS())<lim)spd+=acc*(1000.0f/hge->Timer_GetFPS()); + if(bulletpos.y>610)active=false; + Update_SimpBul(); + } + }bullets[1000]; +public: + double crbrk,llim;TColors col; + void Init(TColors initcol,double _llim) + { + col=initcol;llim=_llim; + crbrk=re.NextDouble(0,frameleft/(double)(AMinute+ThirtySeconds))*(part==36?0.07:0.02)+0.03; + } + void Reverse() + { + if(col==red)col=green; + else if(col==green)col=red; + for(int i=0;i<1000;++i)if(bullets[i].isActive())bullets[i].Reverse(); + } + void achroma2pnt() + { + for(int i=0;i<1000;++i)if(bullets[i].isActive())CreateBullet255(bullets[i].bulletpos.x,bullets[i].bulletpos.y,10); + } + void Update(int msk=0) + { + crbrk-=hge->Timer_GetDelta(); + if(achromab) + { + if(crbrk<=0) + { + crbrk=re.NextDouble(0,frameleft/(double)AMinute)*(part==36?0.07:0.02)+0.03; + for(int i=0;i<1000;++i) + if(!bullets[i].isActive()) + { + bullets[i].achromaInit(vector2d(re.NextDouble(10,790),-5),col,llim); + break; + } + } + for(int i=0;i<1000;++i)if(bullets[i].isActive())bullets[i].achromaUpdate(); + } + else + { + if(crbrk<=0) + { + crbrk=1; + if(msk) + { + memset(achromaB,0,sizeof(achromaB)); + for(int i=0;i<80;++i)achromaB[i]=re.NextInt(0,1); + } + for(int i=0;i<80;++i) + { + if(achromaB[i]&&col==green) + { + for(int j=0;j<1000;++j) + if(!bullets[j].isActive()) + { + bullets[j].achromaInit(vector2d(i*10,-5),col,llim); + break; + } + } + if(!achromaB[i]&&col==red) + { + for(int j=0;j<500;++j) + if(!bullets[j].isActive()) + { + bullets[j].achromaInit(vector2d(i*10,-5),col,llim); + break; + } + } + } + } + for(int i=0;i<500;++i)if(bullets[i].isActive())bullets[i].achromaUpdate(); + } + } +}; +class yellowGroup +{ +private: + int ylw[100]; + bool dirdone[100]; + bool active; +public: + bool isActive(){return active;} + void Init(int _cnt,double _yv) + { + memset(ylw,0,sizeof(ylw));active=true; + memset(dirdone,0,sizeof(dirdone)); + for (int i=0;i<_cnt;++i) + { + int pnt=CreateBullet2(400,300,_yv,frameleft*pi/AMinute+i*(2*pi/_cnt)); + bullet[pnt].alterColor=yellow; + ylw[i]=pnt; + } + } + void Update() + { + bool done=true; + for (int i=0;i<100;++i) + { + if(ylw[i]&&bullet[ylw[i]].lifetime>2&&!dirdone[i]&&bullet[ylw[i]].alterColor==yellow) + bullet[ylw[i]].redir(playerpos),dirdone[i]=true; + if(ylw[i]&&bullet[ylw[i]].lifetime>5&&bullet[ylw[i]].alterColor==yellow) + { + int cc=re.NextInt(0,5); + for(int j=0;j<cc;++j) + { + int pnt=CreateBullet2(bullet[ylw[i]].bulletpos.x,bullet[ylw[i]].bulletpos.y,0,re.NextDouble(-pi,pi)); + if(!re.NextInt(0,3))bullet[pnt].redir(playerpos); + bullet[pnt].bulletaccel=0.002;bullet[pnt].limv=3; + } + BulletEffect_Death(bullet[ylw[i]],ColorToDWORD(yellow)); + bullet[ylw[i]].exist=false; + bullet[ylw[i]].bullettype=0; + ylw[i]=0; + } + else done=false; + } + if(done)active=false; + } +}; +class Spinner +{ +private: + SimpleBullet abullet[40][100]; + int arms; + double rad,rstep; +public: + void Init(int _arms,double _rstep) + { + memset(abullet,0,sizeof(abullet)); + arms=_arms;rstep=_rstep;rad=0; + for(int i=0;i<arms;++i) + for(int j=0;j*rstep<505;++j) + { + abullet[i][j].aC=blue;abullet[i][j].aC2=COLOR_COUNT; + } + } + void Update(double delta) + { + for(int i=0;i<arms;++i) + for(int j=0;j*rstep<505;++j) + { + double crad=rad+i*(2*pi/arms); + abullet[i][j].bulletpos=vector2d(400+j*rstep*cos(crad),300+j*rstep*sin(crad)); + abullet[i][j].Update_SimpBul(); + } + rad+=hge->Timer_GetDelta()*1000*delta; + } +}; +class expSpinner +{ +private: + int bullets[1000]; + int arms,cnt,lc; + double brk,len,dr,da; + bool active; + bool InBound(vector2d pos) + { + if (pos.x<=-25||pos.x>=825||pos.y<=-25||pos.y>=625) + return false;return true; + } +public: + void Init(int _arms,double _drange,double _drad) + { + arms=_arms;lc=cnt=len=0;dr=_drange;da=_drad;active=true; + } + bool isActive(){return active;} + void Update() + { + brk+=hge->Timer_GetDelta(); + if(brk<0.03)return;brk=0; + bool none=true; + for(int i=0;i<arms;++i) + { + double rad=da+i*2*pi/(double)arms,drad=rad+lc*pi/15;int c=(lc&1)?1:-1; + if(InBound(vector2d(400+len*cos(rad),300+len*sin(rad)))) + { + bullets[cnt++]=CreateBullet2( + 400+len*cos(rad),300+len*sin(rad),0,c*drad,true); + c=-c;none=false; + } + } + len+=dr;++lc; + if(none) + { + active=false; + for(int i=0;i<cnt;++i)bullet[bullets[i]].bulletaccel=0.002,bullet[bullets[i]].limv=2; + } + } +}; +class CPinBall +{ +private: + int center; + int circles[10][30]; + int layer,lifetime;double rot,drt; + vector2d delta; +public: + vector2d& Delta(){return delta;} + vector2d& Position(){return bullet[center].bulletpos;} + double Radius(){return layer*10.0-5;} + void Init(vector2d pos,int _lay) + { + center=0;memset(circles,0,sizeof(circles));double speed=re.NextDouble(2,5); + center=CreateBullet2(pos.x,pos.y,speed,re.NextInt(-pi,pi),true); + delta=speed*bullet[center].bulletdir; + layer=_lay;rot=0;lifetime=1;drt=re.NextDouble(-0.5*pi,0.5*pi); + for(int i=0;i<layer;++i) + { + for(int j=0;j<(i+1)*3;++j) + { + circles[i][j]=CreateBullet2(pos.x,pos.y,0,0,true); + bullet[circles[i][j]].bulletpos=vector2d(pos.x+10*i*cos(rot+j*2*pi/((i+1)*3)),pos.y+10*i*sin(rot+j*2*pi/((i+1)*3))); + } + } + } + void Kill() + { + BulletEffect_Death(bullet[center],ColorToDWORD(blue)); + bullet[center].exist=bullet[center].bullettype=0; + for(int i=0;i<layer;++i) + for(int j=0;j<(i+1)*3;++j) + { + BulletEffect_Death(bullet[circles[i][j]],ColorToDWORD(blue)); + bullet[circles[i][j]].exist=bullet[circles[i][j]].bullettype=0; + } + lifetime=0; + } + int& Getlifetime(){return lifetime;} + void UpdateDelta() + { + vector2d tdt=ToUnitCircle(delta); + bullet[center].bulletdir=tdt;bullet[center].bulletspeed=delta.l(); + } + void Update() + { + vector2d pos=bullet[center].bulletpos; + rot+=hge->Timer_GetDelta()*drt; + for(int i=0;i<layer;++i) + for(int j=0;j<(i+1)*3;++j) + bullet[circles[i][j]].bulletpos=vector2d(pos.x+10*i*cos(rot+j*2*pi/((i+1)*3)),pos.y+10*i*sin(rot+j*2*pi/((i+1)*3))); + } +}; +class LineLaser:public Laser +{ +protected: + double width; + vector2d a,b; + DWORD color; +public: + void SetColl(bool col){EnableColl=col;} + void InitLine(vector2d _a,vector2d _b,double _w,DWORD _c) + { + a=_a;b=_b;color=_c;Init(2); + SetTexture(SprSheet,151,264,2,8); + SetWidth(_w);RenCtr=vector2d(0,0); + } + void SetWidth(double _w) + { + width=_w; + vector2d dir(a-b);dir.ToUnitCircle(); + vector2d pd=dir;pd.Rotate(pi/2); + Setdata(0,a-width*pd,a+width*pd,color); + for(int i=1;i<MaxRes;++i)Setdata(i,b-width*pd,b+width*pd,color); + } + double GetWidth(){return width;} + void llsrtopnt(double dis) + { + vector2d dir=a-b;dir.ToUnitCircle();dir=dis*dir; + vector2d x=b; + while(!(x.x<=-25||x.x>=825||x.y<=-25||x.y>=625)) + { + CreateBullet255(x.x,x.y,10); + x=x+dir; + } + } + //use Laser::Process... +}; +class SimpLL:public LineLaser +{ +public: + bool active; + int stp; + double brk; +}; +class SELineLaser +{ +private: + LineLaser lsr; + bool active,h; + double brk,x; +public: + bool isActive(){return active;} + void Init(int _x,bool _h) + { + x=_x;h=_h; + if(h) + lsr.InitLine(vector2d(0,x),vector2d(800,x),0,SETA(ColorToDWORD(blue),0x80)); + else + lsr.InitLine(vector2d(x,0),vector2d(x,600),0,SETA(ColorToDWORD(blue),0x80)); + active=true;brk=0.05; + } + void Update() + { + lsr.Process(); + brk-=hge->Timer_GetDelta(); + if(brk<0) + { + brk=0.05; + lsr.SetWidth(lsr.GetWidth()+0.2); + if(lsr.GetWidth()>1)lsr.SetColl(true); + if(lsr.GetWidth()>6) + { + int t=0; + if(!re.NextInt(0,2)) + { + if(h?playerpos.y>x:playerpos.x>x)t=1; + vector2d px; + vector2d dir=h?vector2d(-1,0):vector2d(0,-1);dir=18*dir; + for(int c=0,tt=t;c<2;++c,dir=-1*dir,tt=t^1) + { + px=h?vector2d(playerpos.x,x):vector2d(x,playerpos.y); + if(c)px=px+dir; + while(!(px.x<=-25||px.x>=825||px.y<=-25||px.y>=625)) + { + tt^=1; + int pnt=CreateBullet2(px.x,px.y,0,0); + bullet[pnt].bulletdir=(tt?1:-1)*(h?vector2d(0,1):vector2d(1,0)); + bullet[pnt].limv=3;bullet[pnt].bulletaccel=0.001; + px=px+dir; + } + } + } + else + { + vector2d dir=h?vector2d(-1,0):vector2d(0,-1);dir=18*dir; + vector2d px=h?vector2d(800+re.NextInt(-18,0),x):vector2d(x,600+re.NextInt(-18,0)); + while(!(px.x<=-25||px.x>=825||px.y<=-25||px.y>=625)) + { + t^=1; + int pnt=CreateBullet2(px.x,px.y,0,0); + bullet[pnt].bulletdir=(t?1:-1)*(h?vector2d(0,1):vector2d(1,0)); + bullet[pnt].limv=3;bullet[pnt].bulletaccel=0.001; + px=px+dir; + } + } + active=false; + } + } + } +}; diff --git a/archive/hge/CxImage/license.txt b/archive/hge/CxImage/license.txt new file mode 100644 index 0000000..1ea1f04 --- /dev/null +++ b/archive/hge/CxImage/license.txt @@ -0,0 +1,48 @@ +This copy of the CxImage notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file ximage.h that is
+included in the CxImage distribution, the latter shall prevail.
+
+If you modify CxImage you may insert additional notices immediately following
+this sentence.
+
+--------------------------------------------------------------------------------
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+CxImage version 7.0.0 31/Dec/2010
+
+CxImage : Copyright (C) 2001 - 2010, Davide Pizzolato
+
+Original CImage and CImageIterator implementation are:
+Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx)
+
+Covered code is provided under this license on an "as is" basis, without warranty
+of any kind, either expressed or implied, including, without limitation, warranties
+that the covered code is free of defects, merchantable, fit for a particular purpose
+or non-infringing. The entire risk as to the quality and performance of the covered
+code is with you. Should any covered code prove defective in any respect, you (not
+the initial developer or any other contributor) assume the cost of any necessary
+servicing, repair or correction. This disclaimer of warranty constitutes an essential
+part of this license. No use of any covered code is authorized hereunder except under
+this disclaimer.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, including commercial applications,
+freely and without fee, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source distribution.
+
+--------------------------------------------------------------------------------
+
+Other information: about CxImage, and the latest version, can be found at the
+CxImage home page: http://www.xdp.it
+
+--------------------------------------------------------------------------------
diff --git a/archive/hge/CxImage/stdint.h b/archive/hge/CxImage/stdint.h new file mode 100644 index 0000000..2e93323 --- /dev/null +++ b/archive/hge/CxImage/stdint.h @@ -0,0 +1,249 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// 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 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 +// 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. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include <limits.h> + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +/*
+#ifdef __cplusplus +extern "C" { +#endif +# include <wchar.h> +#ifdef __cplusplus +} +#endif +*/
+ +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h> +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/archive/hge/CxImage/tif_xfile.cpp b/archive/hge/CxImage/tif_xfile.cpp new file mode 100644 index 0000000..4d1d79a --- /dev/null +++ b/archive/hge/CxImage/tif_xfile.cpp @@ -0,0 +1,221 @@ +/*
+ * TIFF file IO, using CxFile.
+ */
+
+#ifdef WIN32
+ #include <windows.h>
+#endif
+#include <stdio.h>
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_TIF
+
+#include "../tiff/tiffiop.h"
+#include "../tiff/tiffvers.h"
+
+#include "xfile.h"
+
+static tsize_t
+_tiffReadProcEx(thandle_t fd, tdata_t buf, tsize_t size)
+{
+ return (tsize_t)((CxFile*)fd)->Read(buf, 1, size);
+}
+
+static tsize_t
+_tiffWriteProcEx(thandle_t fd, tdata_t buf, tsize_t size)
+{
+ return (tsize_t)((CxFile*)fd)->Write(buf, 1, size);
+}
+
+static toff_t
+_tiffSeekProcEx(thandle_t fd, toff_t off, int whence)
+{
+ if ( off == 0xFFFFFFFF )
+ return 0xFFFFFFFF;
+ if (!((CxFile*)fd)->Seek(off, whence))
+ return 0xFFFFFFFF;
+ if (whence == SEEK_SET)
+ return off;
+
+ return (toff_t)((CxFile*)fd)->Tell();
+}
+
+// Return nonzero if error
+static int
+_tiffCloseProcEx(thandle_t /*fd*/)
+{
+// return !((CxFile*)fd)->Close(); // "//" needed for memory files <DP>
+ return 0;
+}
+
+#include <sys/stat.h>
+
+static toff_t
+_tiffSizeProcEx(thandle_t fd)
+{
+ return ((CxFile*)fd)->Size();
+}
+
+static int
+_tiffMapProcEx(thandle_t /*fd*/, tdata_t* /*pbase*/, toff_t* /*psize*/)
+{
+ return (0);
+}
+
+static void
+_tiffUnmapProcEx(thandle_t /*fd*/, tdata_t /*base*/, toff_t /*size*/)
+{
+}
+
+// Open a TIFF file descriptor for read/writing.
+/*
+TIFF*
+TIFFOpen(const char* name, const char* mode)
+{
+ static const char module[] = "TIFFOpen";
+ FILE* stream = fopen(name, mode);
+ if (stream == NULL)
+ {
+ TIFFError(module, "%s: Cannot open", name);
+ return NULL;
+ }
+ return (TIFFFdOpen((int)stream, name, mode));
+}
+*/
+
+TIFF*
+_TIFFFdOpen(void* fd, const char* name, const char* mode)
+{
+ TIFF* tif;
+
+ tif = TIFFClientOpen(name, mode,
+ (thandle_t) fd,
+ _tiffReadProcEx, _tiffWriteProcEx, _tiffSeekProcEx, _tiffCloseProcEx,
+ _tiffSizeProcEx, _tiffMapProcEx, _tiffUnmapProcEx);
+ if (tif)
+ {
+ tif->tif_fd = (int)fd;
+ }
+ return (tif);
+}
+
+extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode)
+{
+ return (_TIFFFdOpen(stream, "TIFF IMAGE", mode));
+}
+
+#ifdef __GNUC__
+extern char* malloc();
+extern char* realloc();
+#else
+#include <malloc.h>
+#endif
+
+tdata_t
+_TIFFmalloc(tsize_t s)
+{
+ return (malloc((size_t) s));
+}
+
+void
+_TIFFfree(tdata_t p)
+{
+ free(p);
+}
+
+tdata_t
+_TIFFrealloc(tdata_t p, tsize_t s)
+{
+ return (realloc(p, (size_t) s));
+}
+
+void
+_TIFFmemset(tdata_t p, int v, tsize_t c)
+{
+ memset(p, v, (size_t) c);
+}
+
+void
+_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
+{
+ memcpy(d, s, (size_t) c);
+}
+
+int
+_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
+{
+ return (memcmp(p1, p2, (size_t) c));
+}
+
+#ifndef UNICODE
+#define DbgPrint wvsprintf
+#define DbgPrint2 wsprintf
+#define DbgMsgBox MessageBox
+#else
+#define DbgPrint wvsprintfA
+#define DbgPrint2 wsprintfA
+#define DbgMsgBox MessageBoxA
+#endif
+
+static void
+Win32WarningHandler(const char* module, const char* fmt, va_list ap)
+{
+#ifdef _DEBUG
+#if (!defined(_CONSOLE) && !defined(_WIN32_WCE) && defined(WIN32))
+ LPSTR szTitle;
+ LPSTR szTmp;
+ LPCSTR szTitleText = "%s Warning";
+ LPCSTR szDefaultModule = "TIFFLIB";
+ szTmp = (module == NULL) ? (LPSTR)szDefaultModule : (LPSTR)module;
+ if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmp) +
+ strlen(szTitleText) + strlen(fmt) + 128))) == NULL)
+ return;
+ DbgPrint2(szTitle, szTitleText, szTmp);
+ szTmp = szTitle + (strlen(szTitle)+2);
+ DbgPrint(szTmp, fmt, ap);
+ DbgMsgBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
+ LocalFree(szTitle);
+ return;
+#else
+ if (module != NULL)
+ fprintf(stderr, "%s: ", module);
+ fprintf(stderr, "Warning, ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ".\n");
+#endif
+#endif
+}
+TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
+
+static void
+Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
+{
+#ifdef _DEBUG
+#if (!defined(_CONSOLE) && !defined(_WIN32_WCE) && defined(WIN32))
+ LPSTR szTitle;
+ LPSTR szTmp;
+ LPCSTR szTitleText = "%s Error";
+ LPCSTR szDefaultModule = "TIFFLIB";
+ szTmp = (module == NULL) ? (LPSTR)szDefaultModule : (LPSTR)module;
+ if ((szTitle = (LPSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmp) +
+ strlen(szTitleText) + strlen(fmt) + 128))) == NULL)
+ return;
+ DbgPrint2(szTitle, szTitleText, szTmp);
+ szTmp = szTitle + (strlen(szTitle)+2);
+ DbgPrint(szTmp, fmt, ap);
+ DbgMsgBox(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
+ LocalFree(szTitle);
+ return;
+#else
+ if (module != NULL)
+ fprintf(stderr, "%s: ", module);
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ".\n");
+#endif
+#endif
+}
+TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
+
+#endif
+
diff --git a/archive/hge/CxImage/xfile.h b/archive/hge/CxImage/xfile.h new file mode 100644 index 0000000..6de281c --- /dev/null +++ b/archive/hge/CxImage/xfile.h @@ -0,0 +1,79 @@ +/*
+ * File: xfile.h
+ * Purpose: General Purpose File Class
+ */
+/*
+ --------------------------------------------------------------------------------
+
+ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+ CxFile (c) 11/May/2002 Davide Pizzolato - www.xdp.it
+ CxFile version 2.00 23/Aug/2002
+ CxFile version 2.10 16/Dec/2007
+
+ Special thanks to Chris Shearer Cooper for new features, enhancements and bugfixes
+
+ Covered code is provided under this license on an "as is" basis, without warranty
+ of any kind, either expressed or implied, including, without limitation, warranties
+ that the covered code is free of defects, merchantable, fit for a particular purpose
+ or non-infringing. The entire risk as to the quality and performance of the covered
+ code is with you. Should any covered code prove defective in any respect, you (not
+ the initial developer or any other contributor) assume the cost of any necessary
+ servicing, repair or correction. This disclaimer of warranty constitutes an essential
+ part of this license. No use of any covered code is authorized hereunder except under
+ this disclaimer.
+
+ Permission is hereby granted to use, copy, modify, and distribute this
+ source code, or portions hereof, for any purpose, including commercial applications,
+ freely and without fee, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+ --------------------------------------------------------------------------------
+ */
+#if !defined(__xfile_h)
+#define __xfile_h
+
+#if defined (WIN32) || defined (_WIN32_WCE)
+ #include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ximadef.h"
+
+class DLL_EXP CxFile
+{
+public:
+ CxFile(void) { };
+ virtual ~CxFile() { };
+
+ virtual bool Close() = 0;
+ virtual size_t Read(void *buffer, size_t size, size_t count) = 0;
+ virtual size_t Write(const void *buffer, size_t size, size_t count) = 0;
+ virtual bool Seek(int32_t offset, int32_t origin) = 0;
+ virtual int32_t Tell() = 0;
+ virtual int32_t Size() = 0;
+ virtual bool Flush() = 0;
+ virtual bool Eof() = 0;
+ virtual int32_t Error() = 0;
+ virtual bool PutC(uint8_t c)
+ {
+ // Default implementation
+ size_t nWrote = Write(&c, 1, 1);
+ return (bool)(nWrote == 1);
+ }
+ virtual int32_t GetC() = 0;
+ virtual char * GetS(char *string, int32_t n) = 0;
+ virtual int32_t Scanf(const char *format, void* output) = 0;
+};
+
+#endif //__xfile_h
diff --git a/archive/hge/CxImage/ximabmp.cpp b/archive/hge/CxImage/ximabmp.cpp new file mode 100644 index 0000000..c173c7d --- /dev/null +++ b/archive/hge/CxImage/ximabmp.cpp @@ -0,0 +1,448 @@ +/*
+ * File: ximabmp.cpp
+ * Purpose: Platform Independent BMP Image Class Loader and Writer
+ * 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximabmp.h"
+
+#if CXIMAGE_SUPPORT_BMP
+
+#include "ximaiter.h"
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageBMP::Encode(CxFile * hFile)
+{
+
+ if (EncodeSafeCheck(hFile)) return false;
+
+ BITMAPFILEHEADER hdr;
+
+ hdr.bfType = 0x4d42; // 'BM' WINDOWS_BITMAP_SIGNATURE
+ hdr.bfSize = GetSize() + 14 /*sizeof(BITMAPFILEHEADER)*/;
+ hdr.bfReserved1 = hdr.bfReserved2 = 0;
+ hdr.bfOffBits = 14 /*sizeof(BITMAPFILEHEADER)*/ + head.biSize + GetPaletteSize();
+
+ hdr.bfType = m_ntohs(hdr.bfType);
+ hdr.bfSize = m_ntohl(hdr.bfSize);
+ hdr.bfOffBits = m_ntohl(hdr.bfOffBits);
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (GetNumColors()==0 && AlphaIsValid()){
+
+ BITMAPINFOHEADER infohdr;
+ memcpy(&infohdr,&head,sizeof(BITMAPINFOHEADER));
+ infohdr.biCompression = BI_RGB;
+ infohdr.biBitCount = 32;
+ uint32_t dwEffWidth = ((((infohdr.biBitCount * infohdr.biWidth) + 31) / 32) * 4);
+ infohdr.biSizeImage = dwEffWidth * infohdr.biHeight;
+
+ hdr.bfSize = infohdr.biSize + infohdr.biSizeImage + 14 /*sizeof(BITMAPFILEHEADER)*/;
+
+ hdr.bfSize = m_ntohl(hdr.bfSize);
+ bihtoh(&infohdr);
+
+ // Write the file header
+ hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
+ hFile->Write(&infohdr,sizeof(BITMAPINFOHEADER),1);
+ //and DIB+ALPHA interlaced
+ uint8_t *srcalpha = AlphaGetPointer();
+ for(int32_t y = 0; y < infohdr.biHeight; ++y){
+ uint8_t *srcdib = GetBits(y);
+ for(int32_t x = 0; x < infohdr.biWidth; ++x){
+ hFile->Write(srcdib,3,1);
+ hFile->Write(srcalpha,1,1);
+ srcdib += 3;
+ ++srcalpha;
+ }
+ }
+
+ } else
+#endif //CXIMAGE_SUPPORT_ALPHA
+ {
+ // Write the file header
+ hFile->Write(&hdr,min(14,sizeof(BITMAPFILEHEADER)),1);
+ //copy attributes
+ memcpy(pDib,&head,sizeof(BITMAPINFOHEADER));
+ bihtoh((BITMAPINFOHEADER*)pDib);
+ // Write the DIB header and the pixels
+ hFile->Write(pDib,GetSize(),1);
+ bihtoh((BITMAPINFOHEADER*)pDib);
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageBMP::Decode(CxFile * hFile)
+{
+ if (hFile == NULL) return false;
+
+ BITMAPFILEHEADER bf;
+ uint32_t off = hFile->Tell(); //<CSC>
+ cx_try {
+ if (hFile->Read(&bf,min(14,sizeof(bf)),1)==0) cx_throw("Not a BMP");
+
+ bf.bfSize = m_ntohl(bf.bfSize);
+ bf.bfOffBits = m_ntohl(bf.bfOffBits);
+
+ if (m_ntohs(bf.bfType) != BFT_BITMAP) { //do we have a RC HEADER?
+ bf.bfOffBits = 0L;
+ hFile->Seek(off,SEEK_SET);
+ }
+
+ BITMAPINFOHEADER bmpHeader;
+ if (!DibReadBitmapInfo(hFile,&bmpHeader)); cx_throw("Error reading BMP info");
+ uint32_t dwCompression=bmpHeader.biCompression;
+ uint32_t dwBitCount=bmpHeader.biBitCount; //preserve for BI_BITFIELDS compression <Thomas Ernst>
+ bool bIsOldBmp = bmpHeader.biSize == sizeof(BITMAPCOREHEADER);
+
+ bool bTopDownDib = bmpHeader.biHeight<0; //<Flanders> check if it's a top-down bitmap
+ if (bTopDownDib) bmpHeader.biHeight=-bmpHeader.biHeight;
+
+ if (info.nEscape == -1) {
+ // Return output dimensions only
+ head.biWidth = bmpHeader.biWidth;
+ head.biHeight = bmpHeader.biHeight;
+ info.dwType = CXIMAGE_FORMAT_BMP;
+ cx_throw("output dimensions returned");
+ }
+
+ if (!Create(bmpHeader.biWidth,bmpHeader.biHeight,bmpHeader.biBitCount,CXIMAGE_FORMAT_BMP))
+ cx_throw("");
+
+ SetXDPI((int32_t) floor(bmpHeader.biXPelsPerMeter * 254.0 / 10000.0 + 0.5));
+ SetYDPI((int32_t) floor(bmpHeader.biYPelsPerMeter * 254.0 / 10000.0 + 0.5));
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ RGBQUAD *pRgb = GetPalette();
+ if (pRgb){
+ if (bIsOldBmp){
+ // convert a old color table (3 byte entries) to a new
+ // color table (4 byte entries)
+ hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBTRIPLE),1);
+ for (int32_t i=DibNumColors(&head)-1; i>=0; i--){
+ pRgb[i].rgbRed = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
+ pRgb[i].rgbBlue = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
+ pRgb[i].rgbGreen = ((RGBTRIPLE *)pRgb)[i].rgbtGreen;
+ pRgb[i].rgbReserved = (uint8_t)0;
+ }
+ } else {
+ hFile->Read((void*)pRgb,DibNumColors(&bmpHeader) * sizeof(RGBQUAD),1);
+ //force rgbReserved=0, to avoid problems with some WinXp bitmaps
+ for (uint32_t i=0; i<head.biClrUsed; i++) pRgb[i].rgbReserved=0;
+ }
+ }
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ switch (dwBitCount) {
+ case 32 :
+ uint32_t bfmask[3];
+ if (dwCompression == BI_BITFIELDS)
+ {
+ hFile->Read(bfmask, 12, 1);
+ } else {
+ bfmask[0]=0x00FF0000;
+ bfmask[1]=0x0000FF00;
+ bfmask[2]=0x000000FF;
+ }
+ if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
+ if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB){
+ int32_t imagesize=4*head.biHeight*head.biWidth;
+ uint8_t* buff32=(uint8_t*)malloc(imagesize);
+ if (buff32){
+ hFile->Read(buff32, imagesize,1); // read in the pixels
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (dwCompression == BI_RGB){
+ AlphaCreate();
+ if (AlphaIsValid()){
+ bool bAlphaOk = false;
+ uint8_t* p;
+ for (int32_t y=0; y<head.biHeight; y++){
+ p = buff32 + 3 + head.biWidth * 4 * y;
+ for (int32_t x=0; x<head.biWidth; x++){
+ if (*p) bAlphaOk = true;
+ AlphaSet(x,y,*p);
+ p+=4;
+ }
+ }
+ // fix if alpha pixels are all zero
+ if (!bAlphaOk) AlphaInvert();
+ }
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ Bitfield2RGB(buff32,bfmask[0],bfmask[1],bfmask[2],32);
+ free(buff32);
+ } else cx_throw("can't allocate memory");
+ } else cx_throw("unknown compression");
+ break;
+ case 24 :
+ if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
+ if (dwCompression == BI_RGB){
+ hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
+ } else cx_throw("unknown compression");
+ break;
+ case 16 :
+ {
+ uint32_t bfmask[3];
+ if (dwCompression == BI_BITFIELDS)
+ {
+ hFile->Read(bfmask, 12, 1);
+ } else {
+ bfmask[0]=0x7C00; bfmask[1]=0x3E0; bfmask[2]=0x1F; //RGB555
+ }
+ // bf.bfOffBits required after the bitfield mask <Cui Ying Jie>
+ if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
+ // read in the pixels
+ hFile->Read(info.pImage, head.biHeight*((head.biWidth+1)/2)*4,1);
+ // transform into RGB
+ Bitfield2RGB(info.pImage,bfmask[0],bfmask[1],bfmask[2],16);
+ break;
+ }
+ case 8 :
+ case 4 :
+ case 1 :
+ if (bf.bfOffBits != 0L) hFile->Seek(off + bf.bfOffBits,SEEK_SET);
+ switch (dwCompression) {
+ case BI_RGB :
+ hFile->Read(info.pImage, head.biSizeImage,1); // read in the pixels
+ break;
+ case BI_RLE4 :
+ {
+ uint8_t status_byte = 0;
+ uint8_t second_byte = 0;
+ int32_t scanline = 0;
+ int32_t bits = 0;
+ BOOL low_nibble = FALSE;
+ CImageIterator iter(this);
+
+ for (BOOL bContinue = TRUE; bContinue && hFile->Read(&status_byte, sizeof(uint8_t), 1);) {
+
+ switch (status_byte) {
+ case RLE_COMMAND :
+ hFile->Read(&status_byte, sizeof(uint8_t), 1);
+ switch (status_byte) {
+ case RLE_ENDOFLINE :
+ bits = 0;
+ scanline++;
+ low_nibble = FALSE;
+ break;
+ case RLE_ENDOFBITMAP :
+ bContinue=FALSE;
+ break;
+ case RLE_DELTA :
+ {
+ // read the delta values
+ uint8_t delta_x;
+ uint8_t delta_y;
+ hFile->Read(&delta_x, sizeof(uint8_t), 1);
+ hFile->Read(&delta_y, sizeof(uint8_t), 1);
+ // apply them
+ bits += delta_x / 2;
+ scanline += delta_y;
+ break;
+ }
+ default :
+ hFile->Read(&second_byte, sizeof(uint8_t), 1);
+ uint8_t *sline = iter.GetRow(scanline);
+ for (int32_t i = 0; i < status_byte; i++) {
+ if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
+ if (low_nibble) {
+ if (i&1)
+ *(sline + bits) |= (second_byte & 0x0f);
+ else
+ *(sline + bits) |= (second_byte & 0xf0)>>4;
+ bits++;
+ } else {
+ if (i&1)
+ *(sline + bits) = (uint8_t)(second_byte & 0x0f)<<4;
+ else
+ *(sline + bits) = (uint8_t)(second_byte & 0xf0);
+ }
+ }
+
+ if ((i & 1) && (i != (status_byte - 1)))
+ hFile->Read(&second_byte, sizeof(uint8_t), 1);
+
+ low_nibble = !low_nibble;
+ }
+ if ((((status_byte+1) >> 1) & 1 ) == 1)
+ hFile->Read(&second_byte, sizeof(uint8_t), 1);
+ break;
+ };
+ break;
+ default :
+ {
+ uint8_t *sline = iter.GetRow(scanline);
+ hFile->Read(&second_byte, sizeof(uint8_t), 1);
+ for (unsigned i = 0; i < status_byte; i++) {
+ if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
+ if (low_nibble) {
+ if (i&1)
+ *(sline + bits) |= (second_byte & 0x0f);
+ else
+ *(sline + bits) |= (second_byte & 0xf0)>>4;
+ bits++;
+ } else {
+ if (i&1)
+ *(sline + bits) = (uint8_t)(second_byte & 0x0f)<<4;
+ else
+ *(sline + bits) = (uint8_t)(second_byte & 0xf0);
+ }
+ }
+ low_nibble = !low_nibble;
+ }
+ }
+ break;
+ };
+ }
+ break;
+ }
+ case BI_RLE8 :
+ {
+ uint8_t status_byte = 0;
+ uint8_t second_byte = 0;
+ int32_t scanline = 0;
+ int32_t bits = 0;
+ CImageIterator iter(this);
+
+ for (BOOL bContinue = TRUE; bContinue && hFile->Read(&status_byte, sizeof(uint8_t), 1);) {
+ switch (status_byte) {
+ case RLE_COMMAND :
+ hFile->Read(&status_byte, sizeof(uint8_t), 1);
+ switch (status_byte) {
+ case RLE_ENDOFLINE :
+ bits = 0;
+ scanline++;
+ break;
+ case RLE_ENDOFBITMAP :
+ bContinue=FALSE;
+ break;
+ case RLE_DELTA :
+ {
+ // read the delta values
+ uint8_t delta_x;
+ uint8_t delta_y;
+ hFile->Read(&delta_x, sizeof(uint8_t), 1);
+ hFile->Read(&delta_y, sizeof(uint8_t), 1);
+ // apply them
+ bits += delta_x;
+ scanline += delta_y;
+ break;
+ }
+ default :
+ hFile->Read((void *)(iter.GetRow(scanline) + bits), sizeof(uint8_t) * status_byte, 1);
+ // align run length to even number of bytes
+ if ((status_byte & 1) == 1)
+ hFile->Read(&second_byte, sizeof(uint8_t), 1);
+ bits += status_byte;
+ break;
+ };
+ break;
+ default :
+ uint8_t *sline = iter.GetRow(scanline);
+ hFile->Read(&second_byte, sizeof(uint8_t), 1);
+ for (unsigned i = 0; i < status_byte; i++) {
+ if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
+ *(sline + bits) = second_byte;
+ bits++;
+ } else {
+ break;
+ }
+ }
+ break;
+ };
+ }
+ break;
+ }
+ default :
+ cx_throw("compression type not supported");
+ }
+ }
+
+ if (bTopDownDib) Flip(); //<Flanders>
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_BMP) return true;
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/* ReadDibBitmapInfo()
+ *
+ * Will read a file in DIB format and return a global HANDLE to its
+ * BITMAPINFO. This function will work with both "old" and "new"
+ * bitmap formats, but will always return a "new" BITMAPINFO.
+ */
+bool CxImageBMP::DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib)
+{
+ if ((fh==NULL)||(pdib==NULL)) return false;
+
+ if (fh->Read(pdib,sizeof(BITMAPINFOHEADER),1)==0) return false;
+
+ bihtoh(pdib);
+
+ switch (pdib->biSize) // what type of bitmap info is this?
+ {
+ case sizeof(BITMAPINFOHEADER):
+ break;
+
+ case 64: //sizeof(OS2_BMP_HEADER):
+ fh->Seek((int32_t)(64 - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
+ break;
+
+ case 124: //sizeof(BITMAPV5HEADER):
+ fh->Seek((long)(124-sizeof(BITMAPINFOHEADER)), SEEK_CUR);
+ break;
+
+ case sizeof(BITMAPCOREHEADER):
+ {
+ BITMAPCOREHEADER bc = *(BITMAPCOREHEADER*)pdib;
+ pdib->biSize = bc.bcSize;
+ pdib->biWidth = (uint32_t)bc.bcWidth;
+ pdib->biHeight = (uint32_t)bc.bcHeight;
+ pdib->biPlanes = bc.bcPlanes;
+ pdib->biBitCount = bc.bcBitCount;
+ pdib->biCompression = BI_RGB;
+ pdib->biSizeImage = 0;
+ pdib->biXPelsPerMeter = 0;
+ pdib->biYPelsPerMeter = 0;
+ pdib->biClrUsed = 0;
+ pdib->biClrImportant = 0;
+
+ fh->Seek((int32_t)(sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER)), SEEK_CUR);
+ }
+ break;
+ default:
+ //give a last chance
+ if (pdib->biSize>(sizeof(BITMAPINFOHEADER))&&
+ (pdib->biSizeImage>=(uint32_t)(pdib->biHeight*((((pdib->biBitCount*pdib->biWidth)+31)/32)*4)))&&
+ (pdib->biPlanes==1)&&(pdib->biClrUsed==0))
+ {
+ if (pdib->biCompression==BI_RGB)
+ fh->Seek((int32_t)(pdib->biSize - sizeof(BITMAPINFOHEADER)),SEEK_CUR);
+ break;
+ }
+ return false;
+ }
+
+ FixBitmapInfo(pdib);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_BMP
+////////////////////////////////////////////////////////////////////////////////
diff --git a/archive/hge/CxImage/ximabmp.h b/archive/hge/CxImage/ximabmp.h new file mode 100644 index 0000000..c828de5 --- /dev/null +++ b/archive/hge/CxImage/ximabmp.h @@ -0,0 +1,79 @@ +/*
+ * File: ximabmp.h
+ * Purpose: BMP Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageBMP (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
+ *
+ * original CImageBMP and CImageIterator implementation are:
+ * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
+ *
+ * ==========================================================
+ */
+
+#if !defined(__ximaBMP_h)
+#define __ximaBMP_h
+
+#include "ximage.h"
+
+const int32_t RLE_COMMAND = 0;
+const int32_t RLE_ENDOFLINE = 0;
+const int32_t RLE_ENDOFBITMAP = 1;
+const int32_t RLE_DELTA = 2;
+
+#if !defined(BI_RLE8)
+ #define BI_RLE8 1L
+#endif
+#if !defined(BI_RLE4)
+ #define BI_RLE4 2L
+#endif
+
+#if CXIMAGE_SUPPORT_BMP
+
+class CxImageBMP: public CxImage
+{
+public:
+ CxImageBMP(): CxImage(CXIMAGE_FORMAT_BMP) {};
+
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+protected:
+ bool DibReadBitmapInfo(CxFile* fh, BITMAPINFOHEADER *pdib);
+};
+
+#define BFT_ICON 0x4349 /* 'IC' */
+#define BFT_BITMAP 0x4d42 /* 'BM' */
+#define BFT_CURSOR 0x5450 /* 'PT' */
+
+#ifndef WIDTHBYTES
+#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */
+#endif
+
+#endif
+
+#define DibWidthBytesN(lpbi, n) (uint32_t)WIDTHBYTES((uint32_t)(lpbi)->biWidth * (uint32_t)(n))
+#define DibWidthBytes(lpbi) DibWidthBytesN(lpbi, (lpbi)->biBitCount)
+
+#define DibSizeImage(lpbi) ((lpbi)->biSizeImage == 0 \
+ ? ((uint32_t)(uint32_t)DibWidthBytes(lpbi) * (uint32_t)(uint32_t)(lpbi)->biHeight) \
+ : (lpbi)->biSizeImage)
+
+#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
+ ? (int32_t)(1 << (int32_t)(lpbi)->biBitCount) \
+ : (int32_t)(lpbi)->biClrUsed)
+
+#define FixBitmapInfo(lpbi) if ((lpbi)->biSizeImage == 0) \
+ (lpbi)->biSizeImage = DibSizeImage(lpbi); \
+ if ((lpbi)->biClrUsed == 0) \
+ (lpbi)->biClrUsed = DibNumColors(lpbi); \
+
+#endif
diff --git a/archive/hge/CxImage/ximacfg.h b/archive/hge/CxImage/ximacfg.h new file mode 100644 index 0000000..875f517 --- /dev/null +++ b/archive/hge/CxImage/ximacfg.h @@ -0,0 +1,59 @@ +#if !defined(__ximaCFG_h)
+#define __ximaCFG_h
+
+/////////////////////////////////////////////////////////////////////////////
+// CxImage supported features
+#define CXIMAGE_SUPPORT_ALPHA 1
+#define CXIMAGE_SUPPORT_SELECTION 0
+#define CXIMAGE_SUPPORT_TRANSFORMATION 1
+#define CXIMAGE_SUPPORT_DSP 0
+#define CXIMAGE_SUPPORT_LAYERS 0
+#define CXIMAGE_SUPPORT_INTERPOLATION 1
+
+#define CXIMAGE_SUPPORT_DECODE 1
+#define CXIMAGE_SUPPORT_ENCODE 0 //<vho><T.Peck>
+#define CXIMAGE_SUPPORT_WINDOWS 0
+#define CXIMAGE_SUPPORT_EXIF 0
+
+/////////////////////////////////////////////////////////////////////////////
+// CxImage supported formats
+#define CXIMAGE_SUPPORT_BMP 1
+#define CXIMAGE_SUPPORT_GIF 1
+#define CXIMAGE_SUPPORT_JPG 1
+#define CXIMAGE_SUPPORT_PNG 1
+#define CXIMAGE_SUPPORT_ICO 0
+#define CXIMAGE_SUPPORT_TIF 0
+#define CXIMAGE_SUPPORT_TGA 0
+#define CXIMAGE_SUPPORT_PCX 1
+#define CXIMAGE_SUPPORT_WBMP 0
+#define CXIMAGE_SUPPORT_WMF 0
+
+#define CXIMAGE_SUPPORT_JP2 0
+#define CXIMAGE_SUPPORT_JPC 0
+#define CXIMAGE_SUPPORT_PGX 0
+#define CXIMAGE_SUPPORT_PNM 0
+#define CXIMAGE_SUPPORT_RAS 0
+
+#define CXIMAGE_SUPPORT_JBG 0 // GPL'd see ../jbig/copying.txt & ../jbig/patents.htm
+
+#define CXIMAGE_SUPPORT_MNG 0
+#define CXIMAGE_SUPPORT_SKA 0
+#define CXIMAGE_SUPPORT_RAW 0
+#define CXIMAGE_SUPPORT_PSD 0
+
+/////////////////////////////////////////////////////////////////////////////
+#define CXIMAGE_MAX_MEMORY 268435456
+
+#define CXIMAGE_DEFAULT_DPI 96
+
+#define CXIMAGE_ERR_NOFILE "null file handler"
+#define CXIMAGE_ERR_NOIMAGE "null image!!!"
+
+//#define CXIMAGE_SUPPORT_EXCEPTION_HANDLING 1
+//!!Uncomment the last line when releasing
+/////////////////////////////////////////////////////////////////////////////
+//color to grey mapping <H. Muelner> <jurgene>
+//#define RGB2GRAY(r,g,b) (((b)*114 + (g)*587 + (r)*299)/1000)
+#define RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10)
+
+#endif
diff --git a/archive/hge/CxImage/ximadef.h b/archive/hge/CxImage/ximadef.h new file mode 100644 index 0000000..372ec13 --- /dev/null +++ b/archive/hge/CxImage/ximadef.h @@ -0,0 +1,205 @@ +#if !defined(__ximadefs_h)
+#define __ximadefs_h
+
+#include "ximacfg.h"
+
+#if /*defined(_AFXDLL)||*/defined(_USRDLL)
+ #define DLL_EXP __declspec(dllexport)
+#elif defined(_MSC_VER)&&(_MSC_VER<1200)
+ #define DLL_EXP __declspec(dllimport)
+#else
+ #define DLL_EXP
+#endif
+
+
+#if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ #define cx_try try
+ #define cx_throw(message) throw(message)
+ #define cx_catch catch (const char *message)
+#else
+ #define cx_try bool cx_error=false;
+ #define cx_throw(message) {cx_error=true; if(strcmp(message,"")) strncpy(info.szLastError,message,255); goto cx_error_catch;}
+ #define cx_catch cx_error_catch: char message[]=""; if(cx_error)
+#endif
+
+
+#if CXIMAGE_SUPPORT_JP2 || CXIMAGE_SUPPORT_JPC || CXIMAGE_SUPPORT_PGX || CXIMAGE_SUPPORT_PNM || CXIMAGE_SUPPORT_RAS
+ #define CXIMAGE_SUPPORT_JASPER 1
+#else
+ #define CXIMAGE_SUPPORT_JASPER 0
+#endif
+
+#if CXIMAGE_SUPPORT_DSP
+#undef CXIMAGE_SUPPORT_TRANSFORMATION
+ #define CXIMAGE_SUPPORT_TRANSFORMATION 1
+#endif
+
+#if CXIMAGE_SUPPORT_TRANSFORMATION || CXIMAGE_SUPPORT_TIF || CXIMAGE_SUPPORT_TGA || CXIMAGE_SUPPORT_BMP || CXIMAGE_SUPPORT_WINDOWS
+ #define CXIMAGE_SUPPORT_BASICTRANSFORMATIONS 1
+#endif
+
+#if CXIMAGE_SUPPORT_DSP || CXIMAGE_SUPPORT_TRANSFORMATION
+#undef CXIMAGE_SUPPORT_INTERPOLATION
+ #define CXIMAGE_SUPPORT_INTERPOLATION 1
+#endif
+
+#if defined (_WIN32_WCE)
+ #undef CXIMAGE_SUPPORT_WMF
+ #define CXIMAGE_SUPPORT_WMF 0
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE)
+ #undef CXIMAGE_SUPPORT_WINDOWS
+ #define CXIMAGE_SUPPORT_WINDOWS 0
+#endif
+
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
+#ifndef PI
+ #define PI 3.141592653589793f
+#endif
+
+
+#if defined(WIN32) || defined(_WIN32_WCE)
+#include <windows.h>
+#include <tchar.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+
+#ifdef __BORLANDC__
+
+#ifndef _COMPLEX_DEFINED
+
+typedef struct tagcomplex {
+ double x,y;
+} _complex;
+
+#endif
+
+#define _cabs(c) sqrt(c.x*c.x+c.y*c.y)
+
+#endif
+
+#if defined(WIN32) || defined(_WIN32_WCE)
+ #include "stdint.h"
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE)
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef uint32_t COLORREF;
+typedef void* HANDLE;
+typedef void* HRGN;
+
+#ifndef BOOL
+#define BOOL bool
+#endif
+
+#ifndef TRUE
+#define TRUE true
+#endif
+
+#ifndef FALSE
+#define FALSE false
+#endif
+
+#ifndef TCHAR
+#define TCHAR char
+#define _T
+#endif
+
+typedef struct tagRECT
+{
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+} RECT;
+
+typedef struct tagPOINT
+{
+ int32_t x;
+ int32_t y;
+} POINT;
+
+typedef struct tagRGBQUAD {
+ uint8_t rgbBlue;
+ uint8_t rgbGreen;
+ uint8_t rgbRed;
+ uint8_t rgbReserved;
+} RGBQUAD;
+
+#pragma pack(1)
+
+typedef struct tagBITMAPINFOHEADER{
+ uint32_t biSize;
+ int32_t biWidth;
+ int32_t biHeight;
+ uint16_t biPlanes;
+ uint16_t biBitCount;
+ uint32_t biCompression;
+ uint32_t biSizeImage;
+ int32_t biXPelsPerMeter;
+ int32_t biYPelsPerMeter;
+ uint32_t biClrUsed;
+ uint32_t biClrImportant;
+} BITMAPINFOHEADER;
+
+typedef struct tagBITMAPFILEHEADER {
+ uint16_t bfType;
+ uint32_t bfSize;
+ uint16_t bfReserved1;
+ uint16_t bfReserved2;
+ uint32_t bfOffBits;
+} BITMAPFILEHEADER;
+
+typedef struct tagBITMAPCOREHEADER {
+ uint32_t bcSize;
+ uint16_t bcWidth;
+ uint16_t bcHeight;
+ uint16_t bcPlanes;
+ uint16_t bcBitCount;
+} BITMAPCOREHEADER;
+
+typedef struct tagRGBTRIPLE {
+ uint8_t rgbtBlue;
+ uint8_t rgbtGreen;
+ uint8_t rgbtRed;
+} RGBTRIPLE;
+
+#pragma pack()
+
+#define BI_RGB 0L
+#define BI_RLE8 1L
+#define BI_RLE4 2L
+#define BI_BITFIELDS 3L
+
+#define GetRValue(rgb) ((uint8_t)(rgb))
+#define GetGValue(rgb) ((uint8_t)(((uint16_t)(rgb)) >> 8))
+#define GetBValue(rgb) ((uint8_t)((rgb)>>16))
+#define RGB(r,g,b) ((COLORREF)(((uint8_t)(r)|((uint16_t)((uint8_t)(g))<<8))|(((uint32_t)(uint8_t)(b))<<16)))
+
+#ifndef _COMPLEX_DEFINED
+
+typedef struct tagcomplex {
+ double x,y;
+} _complex;
+
+#endif
+
+#define _cabs(c) sqrt(c.x*c.x+c.y*c.y)
+
+#endif
+
+#endif //__ximadefs
diff --git a/archive/hge/CxImage/ximadsp.cpp b/archive/hge/CxImage/ximadsp.cpp new file mode 100644 index 0000000..df73136 --- /dev/null +++ b/archive/hge/CxImage/ximadsp.cpp @@ -0,0 +1,3771 @@ +// xImaDsp.cpp : DSP functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#include "ximaiter.h"
+
+#if CXIMAGE_SUPPORT_DSP
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Converts the image to B&W.
+ * The OptimalThreshold() function can be used for calculating the optimal threshold.
+ * \param level: the lightness threshold.
+ * \return true if everything is ok
+ */
+bool CxImage::Threshold(uint8_t level)
+{
+ if (!pDib) return false;
+ if (head.biBitCount == 1) return true;
+
+ GrayScale();
+
+ CxImage tmp(head.biWidth,head.biHeight,1);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ if (BlindGetPixelIndex(x,y)>level)
+ tmp.BlindSetPixelIndex(x,y,1);
+ else
+ tmp.BlindSetPixelIndex(x,y,0);
+ }
+ }
+ tmp.SetPaletteColor(0,0,0,0);
+ tmp.SetPaletteColor(1,255,255,255);
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Converts the image to B&W, using a threshold mask
+ * \param pThresholdMask: the lightness threshold mask.
+ * the pThresholdMask image must be grayscale with same with and height of the current image
+ * \return true if everything is ok
+ */
+bool CxImage::Threshold(CxImage* pThresholdMask)
+{
+ if (!pDib) return false;
+ if (head.biBitCount == 1) return true;
+
+ if (!pThresholdMask) return false;
+
+ if (!pThresholdMask->IsValid() ||
+ !pThresholdMask->IsGrayScale() ||
+ pThresholdMask->GetWidth() != GetWidth() ||
+ pThresholdMask->GetHeight() != GetHeight()){
+ strcpy(info.szLastError,"invalid ThresholdMask");
+ return false;
+ }
+
+ GrayScale();
+
+ CxImage tmp(head.biWidth,head.biHeight,1);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ if (BlindGetPixelIndex(x,y)>pThresholdMask->BlindGetPixelIndex(x,y))
+ tmp.BlindSetPixelIndex(x,y,1);
+ else
+ tmp.BlindSetPixelIndex(x,y,0);
+ }
+ }
+ tmp.SetPaletteColor(0,0,0,0);
+ tmp.SetPaletteColor(1,255,255,255);
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Filters only the pixels with a lightness less (or more) than the threshold level,
+ * and preserves the colors for the unfiltered pixels.
+ * \param level = the lightness threshold.
+ * \param bDirection = false: filter dark pixels, true: filter light pixels
+ * \param nBkgndColor = filtered pixels are set to nBkgndColor color
+ * \param bSetAlpha = if true, sets also the alpha component for the filtered pixels, with nBkgndColor.rgbReserved
+ * \return true if everything is ok
+ * \author [DP], [wangsongtao]
+ */
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Threshold2(uint8_t level, bool bDirection, RGBQUAD nBkgndColor, bool bSetAlpha)
+{
+ if (!pDib) return false;
+ if (head.biBitCount == 1) return true;
+
+ CxImage tmp(*this, true, false, false);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ tmp.GrayScale();
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ uint8_t i = tmp.BlindGetPixelIndex(x,y);
+ if (!bDirection && i<level) BlindSetPixelColor(x,y,nBkgndColor,bSetAlpha);
+ if (bDirection && i>=level) BlindSetPixelColor(x,y,nBkgndColor,bSetAlpha);
+ }
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Extract RGB channels from the image. Each channel is an 8 bit grayscale image.
+ * \param r,g,b: pointers to CxImage objects, to store the splited channels
+ * \return true if everything is ok
+ */
+bool CxImage::SplitRGB(CxImage* r,CxImage* g,CxImage* b)
+{
+ if (!pDib) return false;
+ if (r==NULL && g==NULL && b==NULL) return false;
+
+ CxImage tmpr(head.biWidth,head.biHeight,8);
+ CxImage tmpg(head.biWidth,head.biHeight,8);
+ CxImage tmpb(head.biWidth,head.biHeight,8);
+
+ RGBQUAD color;
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ color = BlindGetPixelColor(x,y);
+ if (r) tmpr.BlindSetPixelIndex(x,y,color.rgbRed);
+ if (g) tmpg.BlindSetPixelIndex(x,y,color.rgbGreen);
+ if (b) tmpb.BlindSetPixelIndex(x,y,color.rgbBlue);
+ }
+ }
+
+ if (r) tmpr.SetGrayPalette();
+ if (g) tmpg.SetGrayPalette();
+ if (b) tmpb.SetGrayPalette();
+
+ /*for(int32_t j=0; j<256; j++){
+ uint8_t i=(uint8_t)j;
+ if (r) tmpr.SetPaletteColor(i,i,0,0);
+ if (g) tmpg.SetPaletteColor(i,0,i,0);
+ if (b) tmpb.SetPaletteColor(i,0,0,i);
+ }*/
+
+ if (r) r->Transfer(tmpr);
+ if (g) g->Transfer(tmpg);
+ if (b) b->Transfer(tmpb);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Extract CMYK channels from the image. Each channel is an 8 bit grayscale image.
+ * \param c,m,y,k: pointers to CxImage objects, to store the splited channels
+ * \return true if everything is ok
+ */
+bool CxImage::SplitCMYK(CxImage* c,CxImage* m,CxImage* y,CxImage* k)
+{
+ if (!pDib) return false;
+ if (c==NULL && m==NULL && y==NULL && k==NULL) return false;
+
+ CxImage tmpc(head.biWidth,head.biHeight,8);
+ CxImage tmpm(head.biWidth,head.biHeight,8);
+ CxImage tmpy(head.biWidth,head.biHeight,8);
+ CxImage tmpk(head.biWidth,head.biHeight,8);
+
+ RGBQUAD color;
+ for(int32_t yy=0; yy<head.biHeight; yy++){
+ for(int32_t xx=0; xx<head.biWidth; xx++){
+ color = BlindGetPixelColor(xx,yy);
+ if (c) tmpc.BlindSetPixelIndex(xx,yy,(uint8_t)(255-color.rgbRed));
+ if (m) tmpm.BlindSetPixelIndex(xx,yy,(uint8_t)(255-color.rgbGreen));
+ if (y) tmpy.BlindSetPixelIndex(xx,yy,(uint8_t)(255-color.rgbBlue));
+ if (k) tmpk.BlindSetPixelIndex(xx,yy,(uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue));
+ }
+ }
+
+ if (c) tmpc.SetGrayPalette();
+ if (m) tmpm.SetGrayPalette();
+ if (y) tmpy.SetGrayPalette();
+ if (k) tmpk.SetGrayPalette();
+
+ if (c) c->Transfer(tmpc);
+ if (m) m->Transfer(tmpm);
+ if (y) y->Transfer(tmpy);
+ if (k) k->Transfer(tmpk);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Extract YUV channels from the image. Each channel is an 8 bit grayscale image.
+ * \param y,u,v: pointers to CxImage objects, to store the splited channels
+ * \return true if everything is ok
+ */
+bool CxImage::SplitYUV(CxImage* y,CxImage* u,CxImage* v)
+{
+ if (!pDib) return false;
+ if (y==NULL && u==NULL && v==NULL) return false;
+
+ CxImage tmpy(head.biWidth,head.biHeight,8);
+ CxImage tmpu(head.biWidth,head.biHeight,8);
+ CxImage tmpv(head.biWidth,head.biHeight,8);
+
+ RGBQUAD color;
+ for(int32_t yy=0; yy<head.biHeight; yy++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ color = RGBtoYUV(BlindGetPixelColor(x,yy));
+ if (y) tmpy.BlindSetPixelIndex(x,yy,color.rgbRed);
+ if (u) tmpu.BlindSetPixelIndex(x,yy,color.rgbGreen);
+ if (v) tmpv.BlindSetPixelIndex(x,yy,color.rgbBlue);
+ }
+ }
+
+ if (y) tmpy.SetGrayPalette();
+ if (u) tmpu.SetGrayPalette();
+ if (v) tmpv.SetGrayPalette();
+
+ if (y) y->Transfer(tmpy);
+ if (u) u->Transfer(tmpu);
+ if (v) v->Transfer(tmpv);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Extract YIQ channels from the image. Each channel is an 8 bit grayscale image.
+ * \param y,i,q: pointers to CxImage objects, to store the splited channels
+ * \return true if everything is ok
+ */
+bool CxImage::SplitYIQ(CxImage* y,CxImage* i,CxImage* q)
+{
+ if (!pDib) return false;
+ if (y==NULL && i==NULL && q==NULL) return false;
+
+ CxImage tmpy(head.biWidth,head.biHeight,8);
+ CxImage tmpi(head.biWidth,head.biHeight,8);
+ CxImage tmpq(head.biWidth,head.biHeight,8);
+
+ RGBQUAD color;
+ for(int32_t yy=0; yy<head.biHeight; yy++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ color = RGBtoYIQ(BlindGetPixelColor(x,yy));
+ if (y) tmpy.BlindSetPixelIndex(x,yy,color.rgbRed);
+ if (i) tmpi.BlindSetPixelIndex(x,yy,color.rgbGreen);
+ if (q) tmpq.BlindSetPixelIndex(x,yy,color.rgbBlue);
+ }
+ }
+
+ if (y) tmpy.SetGrayPalette();
+ if (i) tmpi.SetGrayPalette();
+ if (q) tmpq.SetGrayPalette();
+
+ if (y) y->Transfer(tmpy);
+ if (i) i->Transfer(tmpi);
+ if (q) q->Transfer(tmpq);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Extract XYZ channels from the image. Each channel is an 8 bit grayscale image.
+ * \param x,y,z: pointers to CxImage objects, to store the splited channels
+ * \return true if everything is ok
+ */
+bool CxImage::SplitXYZ(CxImage* x,CxImage* y,CxImage* z)
+{
+ if (!pDib) return false;
+ if (x==NULL && y==NULL && z==NULL) return false;
+
+ CxImage tmpx(head.biWidth,head.biHeight,8);
+ CxImage tmpy(head.biWidth,head.biHeight,8);
+ CxImage tmpz(head.biWidth,head.biHeight,8);
+
+ RGBQUAD color;
+ for(int32_t yy=0; yy<head.biHeight; yy++){
+ for(int32_t xx=0; xx<head.biWidth; xx++){
+ color = RGBtoXYZ(BlindGetPixelColor(xx,yy));
+ if (x) tmpx.BlindSetPixelIndex(xx,yy,color.rgbRed);
+ if (y) tmpy.BlindSetPixelIndex(xx,yy,color.rgbGreen);
+ if (z) tmpz.BlindSetPixelIndex(xx,yy,color.rgbBlue);
+ }
+ }
+
+ if (x) tmpx.SetGrayPalette();
+ if (y) tmpy.SetGrayPalette();
+ if (z) tmpz.SetGrayPalette();
+
+ if (x) x->Transfer(tmpx);
+ if (y) y->Transfer(tmpy);
+ if (z) z->Transfer(tmpz);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Extract HSL channels from the image. Each channel is an 8 bit grayscale image.
+ * \param h,s,l: pointers to CxImage objects, to store the splited channels
+ * \return true if everything is ok
+ */
+bool CxImage::SplitHSL(CxImage* h,CxImage* s,CxImage* l)
+{
+ if (!pDib) return false;
+ if (h==NULL && s==NULL && l==NULL) return false;
+
+ CxImage tmph(head.biWidth,head.biHeight,8);
+ CxImage tmps(head.biWidth,head.biHeight,8);
+ CxImage tmpl(head.biWidth,head.biHeight,8);
+
+ RGBQUAD color;
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ color = RGBtoHSL(BlindGetPixelColor(x,y));
+ if (h) tmph.BlindSetPixelIndex(x,y,color.rgbRed);
+ if (s) tmps.BlindSetPixelIndex(x,y,color.rgbGreen);
+ if (l) tmpl.BlindSetPixelIndex(x,y,color.rgbBlue);
+ }
+ }
+
+ if (h) tmph.SetGrayPalette();
+ if (s) tmps.SetGrayPalette();
+ if (l) tmpl.SetGrayPalette();
+
+ /* pseudo-color generator for hue channel (visual debug)
+ if (h) for(int32_t j=0; j<256; j++){
+ uint8_t i=(uint8_t)j;
+ RGBQUAD hsl={120,240,i,0};
+ tmph.SetPaletteColor(i,HSLtoRGB(hsl));
+ }*/
+
+ if (h) h->Transfer(tmph);
+ if (s) s->Transfer(tmps);
+ if (l) l->Transfer(tmpl);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#define HSLMAX 255 /* H,L, and S vary over 0-HSLMAX */
+#define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
+ /* HSLMAX BEST IF DIVISIBLE BY 6 */
+ /* RGBMAX, HSLMAX must each fit in a uint8_t. */
+/* Hue is undefined if Saturation is 0 (grey-scale) */
+/* This value determines where the Hue scrollbar is */
+/* initially set for achromatic colors */
+#define HSLUNDEFINED (HSLMAX*2/3)
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::RGBtoHSL(RGBQUAD lRGBColor)
+{
+ uint8_t R,G,B; /* input RGB values */
+ uint8_t H,L,S; /* output HSL values */
+ uint8_t cMax,cMin; /* max and min RGB values */
+ uint16_t Rdelta,Gdelta,Bdelta; /* intermediate value: % of spread from max*/
+
+ R = lRGBColor.rgbRed; /* get R, G, and B out of uint32_t */
+ G = lRGBColor.rgbGreen;
+ B = lRGBColor.rgbBlue;
+
+ cMax = max( max(R,G), B); /* calculate lightness */
+ cMin = min( min(R,G), B);
+ L = (uint8_t)((((cMax+cMin)*HSLMAX)+RGBMAX)/(2*RGBMAX));
+
+ if (cMax==cMin){ /* r=g=b --> achromatic case */
+ S = 0; /* saturation */
+ H = HSLUNDEFINED; /* hue */
+ } else { /* chromatic case */
+ if (L <= (HSLMAX/2)) /* saturation */
+ S = (uint8_t)((((cMax-cMin)*HSLMAX)+((cMax+cMin)/2))/(cMax+cMin));
+ else
+ S = (uint8_t)((((cMax-cMin)*HSLMAX)+((2*RGBMAX-cMax-cMin)/2))/(2*RGBMAX-cMax-cMin));
+ /* hue */
+ Rdelta = (uint16_t)((((cMax-R)*(HSLMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
+ Gdelta = (uint16_t)((((cMax-G)*(HSLMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
+ Bdelta = (uint16_t)((((cMax-B)*(HSLMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
+
+ if (R == cMax)
+ H = (uint8_t)(Bdelta - Gdelta);
+ else if (G == cMax)
+ H = (uint8_t)((HSLMAX/3) + Rdelta - Bdelta);
+ else /* B == cMax */
+ H = (uint8_t)(((2*HSLMAX)/3) + Gdelta - Rdelta);
+
+// if (H < 0) H += HSLMAX; //always false
+ if (H > HSLMAX) H -= HSLMAX;
+ }
+ RGBQUAD hsl={L,S,H,0};
+ return hsl;
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::HueToRGB(float n1,float n2, float hue)
+{
+ //<F. Livraghi> fixed implementation for HSL2RGB routine
+ float rValue;
+
+ if (hue > 360)
+ hue = hue - 360;
+ else if (hue < 0)
+ hue = hue + 360;
+
+ if (hue < 60)
+ rValue = n1 + (n2-n1)*hue/60.0f;
+ else if (hue < 180)
+ rValue = n2;
+ else if (hue < 240)
+ rValue = n1+(n2-n1)*(240-hue)/60;
+ else
+ rValue = n1;
+
+ return rValue;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::HSLtoRGB(COLORREF cHSLColor)
+{
+ return HSLtoRGB(RGBtoRGBQUAD(cHSLColor));
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::HSLtoRGB(RGBQUAD lHSLColor)
+{
+ //<F. Livraghi> fixed implementation for HSL2RGB routine
+ float h,s,l;
+ float m1,m2;
+ uint8_t r,g,b;
+
+ h = (float)lHSLColor.rgbRed * 360.0f/255.0f;
+ s = (float)lHSLColor.rgbGreen/255.0f;
+ l = (float)lHSLColor.rgbBlue/255.0f;
+
+ if (l <= 0.5) m2 = l * (1+s);
+ else m2 = l + s - l*s;
+
+ m1 = 2 * l - m2;
+
+ if (s == 0) {
+ r=g=b=(uint8_t)(l*255.0f);
+ } else {
+ r = (uint8_t)(HueToRGB(m1,m2,h+120) * 255.0f);
+ g = (uint8_t)(HueToRGB(m1,m2,h) * 255.0f);
+ b = (uint8_t)(HueToRGB(m1,m2,h-120) * 255.0f);
+ }
+
+ RGBQUAD rgb = {b,g,r,0};
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::YUVtoRGB(RGBQUAD lYUVColor)
+{
+ int32_t U,V,R,G,B;
+ float Y = lYUVColor.rgbRed;
+ U = lYUVColor.rgbGreen - 128;
+ V = lYUVColor.rgbBlue - 128;
+
+// R = (int32_t)(1.164 * Y + 2.018 * U);
+// G = (int32_t)(1.164 * Y - 0.813 * V - 0.391 * U);
+// B = (int32_t)(1.164 * Y + 1.596 * V);
+ R = (int32_t)( Y + 1.403f * V);
+ G = (int32_t)( Y - 0.344f * U - 0.714f * V);
+ B = (int32_t)( Y + 1.770f * U);
+
+ R= min(255,max(0,R));
+ G= min(255,max(0,G));
+ B= min(255,max(0,B));
+ RGBQUAD rgb={(uint8_t)B,(uint8_t)G,(uint8_t)R,0};
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::RGBtoYUV(RGBQUAD lRGBColor)
+{
+ int32_t Y,U,V,R,G,B;
+ R = lRGBColor.rgbRed;
+ G = lRGBColor.rgbGreen;
+ B = lRGBColor.rgbBlue;
+
+// Y = (int32_t)( 0.257 * R + 0.504 * G + 0.098 * B);
+// U = (int32_t)( 0.439 * R - 0.368 * G - 0.071 * B + 128);
+// V = (int32_t)(-0.148 * R - 0.291 * G + 0.439 * B + 128);
+ Y = (int32_t)(0.299f * R + 0.587f * G + 0.114f * B);
+ U = (int32_t)((B-Y) * 0.565f + 128);
+ V = (int32_t)((R-Y) * 0.713f + 128);
+
+ Y= min(255,max(0,Y));
+ U= min(255,max(0,U));
+ V= min(255,max(0,V));
+ RGBQUAD yuv={(uint8_t)V,(uint8_t)U,(uint8_t)Y,0};
+ return yuv;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::YIQtoRGB(RGBQUAD lYIQColor)
+{
+ int32_t I,Q,R,G,B;
+ float Y = lYIQColor.rgbRed;
+ I = lYIQColor.rgbGreen - 128;
+ Q = lYIQColor.rgbBlue - 128;
+
+ R = (int32_t)( Y + 0.956f * I + 0.621f * Q);
+ G = (int32_t)( Y - 0.273f * I - 0.647f * Q);
+ B = (int32_t)( Y - 1.104f * I + 1.701f * Q);
+
+ R= min(255,max(0,R));
+ G= min(255,max(0,G));
+ B= min(255,max(0,B));
+ RGBQUAD rgb={(uint8_t)B,(uint8_t)G,(uint8_t)R,0};
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::RGBtoYIQ(RGBQUAD lRGBColor)
+{
+ int32_t Y,I,Q,R,G,B;
+ R = lRGBColor.rgbRed;
+ G = lRGBColor.rgbGreen;
+ B = lRGBColor.rgbBlue;
+
+ Y = (int32_t)( 0.2992f * R + 0.5868f * G + 0.1140f * B);
+ I = (int32_t)( 0.5960f * R - 0.2742f * G - 0.3219f * B + 128);
+ Q = (int32_t)( 0.2109f * R - 0.5229f * G + 0.3120f * B + 128);
+
+ Y= min(255,max(0,Y));
+ I= min(255,max(0,I));
+ Q= min(255,max(0,Q));
+ RGBQUAD yiq={(uint8_t)Q,(uint8_t)I,(uint8_t)Y,0};
+ return yiq;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::XYZtoRGB(RGBQUAD lXYZColor)
+{
+ int32_t X,Y,Z,R,G,B;
+ X = lXYZColor.rgbRed;
+ Y = lXYZColor.rgbGreen;
+ Z = lXYZColor.rgbBlue;
+ double k=1.088751;
+
+ R = (int32_t)( 3.240479f * X - 1.537150f * Y - 0.498535f * Z * k);
+ G = (int32_t)( -0.969256f * X + 1.875992f * Y + 0.041556f * Z * k);
+ B = (int32_t)( 0.055648f * X - 0.204043f * Y + 1.057311f * Z * k);
+
+ R= min(255,max(0,R));
+ G= min(255,max(0,G));
+ B= min(255,max(0,B));
+ RGBQUAD rgb={(uint8_t)B,(uint8_t)G,(uint8_t)R,0};
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::RGBtoXYZ(RGBQUAD lRGBColor)
+{
+ int32_t X,Y,Z,R,G,B;
+ R = lRGBColor.rgbRed;
+ G = lRGBColor.rgbGreen;
+ B = lRGBColor.rgbBlue;
+
+ X = (int32_t)( 0.412453f * R + 0.357580f * G + 0.180423f * B);
+ Y = (int32_t)( 0.212671f * R + 0.715160f * G + 0.072169f * B);
+ Z = (int32_t)((0.019334f * R + 0.119193f * G + 0.950227f * B)*0.918483657f);
+
+ //X= min(255,max(0,X));
+ //Y= min(255,max(0,Y));
+ //Z= min(255,max(0,Z));
+ RGBQUAD xyz={(uint8_t)Z,(uint8_t)Y,(uint8_t)X,0};
+ return xyz;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Generates a "rainbow" palette with saturated colors
+ * \param correction: 1 generates a single hue spectrum. 0.75 is nice for scientific applications.
+ */
+void CxImage::HuePalette(float correction)
+{
+ if (head.biClrUsed==0) return;
+
+ for(uint32_t j=0; j<head.biClrUsed; j++){
+ uint8_t i=(uint8_t)(j*correction*(255/(head.biClrUsed-1)));
+ RGBQUAD hsl={120,240,i,0};
+ SetPaletteColor((uint8_t)j,HSLtoRGB(hsl));
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Replaces the original hue and saturation values.
+ * \param hue: hue
+ * \param sat: saturation
+ * \param blend: can be from 0 (no effect) to 1 (full effect)
+ * \return true if everything is ok
+ */
+bool CxImage::Colorize(uint8_t hue, uint8_t sat, float blend)
+{
+ if (!pDib) return false;
+
+ if (blend < 0.0f) blend = 0.0f;
+ if (blend > 1.0f) blend = 1.0f;
+ int32_t a0 = (int32_t)(256*blend);
+ int32_t a1 = 256 - a0;
+
+ bool bFullBlend = false;
+ if (blend > 0.999f) bFullBlend = true;
+
+ RGBQUAD color,hsl;
+ if (head.biClrUsed==0){
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ if (bFullBlend){
+ color = RGBtoHSL(BlindGetPixelColor(x,y));
+ color.rgbRed=hue;
+ color.rgbGreen=sat;
+ BlindSetPixelColor(x,y,HSLtoRGB(color));
+ } else {
+ color = BlindGetPixelColor(x,y);
+ hsl.rgbRed=hue;
+ hsl.rgbGreen=sat;
+ hsl.rgbBlue = (uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
+ hsl = HSLtoRGB(hsl);
+ //BlendPixelColor(x,y,hsl,blend);
+ //color.rgbRed = (uint8_t)(hsl.rgbRed * blend + color.rgbRed * (1.0f - blend));
+ //color.rgbBlue = (uint8_t)(hsl.rgbBlue * blend + color.rgbBlue * (1.0f - blend));
+ //color.rgbGreen = (uint8_t)(hsl.rgbGreen * blend + color.rgbGreen * (1.0f - blend));
+ color.rgbRed = (uint8_t)((hsl.rgbRed * a0 + color.rgbRed * a1)>>8);
+ color.rgbBlue = (uint8_t)((hsl.rgbBlue * a0 + color.rgbBlue * a1)>>8);
+ color.rgbGreen = (uint8_t)((hsl.rgbGreen * a0 + color.rgbGreen * a1)>>8);
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+ }
+ } else {
+ for(uint32_t j=0; j<head.biClrUsed; j++){
+ if (bFullBlend){
+ color = RGBtoHSL(GetPaletteColor((uint8_t)j));
+ color.rgbRed=hue;
+ color.rgbGreen=sat;
+ SetPaletteColor((uint8_t)j,HSLtoRGB(color));
+ } else {
+ color = GetPaletteColor((uint8_t)j);
+ hsl.rgbRed=hue;
+ hsl.rgbGreen=sat;
+ hsl.rgbBlue = (uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
+ hsl = HSLtoRGB(hsl);
+ color.rgbRed = (uint8_t)(hsl.rgbRed * blend + color.rgbRed * (1.0f - blend));
+ color.rgbBlue = (uint8_t)(hsl.rgbBlue * blend + color.rgbBlue * (1.0f - blend));
+ color.rgbGreen = (uint8_t)(hsl.rgbGreen * blend + color.rgbGreen * (1.0f - blend));
+ SetPaletteColor((uint8_t)j,color);
+ }
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Changes the brightness and the contrast of the image.
+ * \param brightness: can be from -255 to 255, if brightness is negative, the image becomes dark.
+ * \param contrast: can be from -100 to 100, the neutral value is 0.
+ * \return true if everything is ok
+ */
+bool CxImage::Light(int32_t brightness, int32_t contrast)
+{
+ if (!pDib) return false;
+ float c=(100 + contrast)/100.0f;
+ brightness+=128;
+
+ uint8_t cTable[256]; //<nipper>
+ for (int32_t i=0;i<256;i++) {
+ cTable[i] = (uint8_t)max(0,min(255,(int32_t)((i-128)*c + brightness + 0.5f)));
+ }
+
+ return Lut(cTable);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return mean lightness of the image. Useful with Threshold() and Light()
+ */
+float CxImage::Mean()
+{
+ if (!pDib) return 0;
+
+ CxImage tmp(*this,true);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ tmp.GrayScale();
+ float sum=0;
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+ if (xmin==xmax || ymin==ymax) return (float)0.0;
+
+ uint8_t *iSrc=tmp.info.pImage;
+ iSrc += tmp.info.dwEffWidth*ymin; // necessary for selections <Admir Hodzic>
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin)); //<zhanghk><Anatoly Ivasyuk>
+ for(int32_t x=xmin; x<xmax; x++){
+ sum+=iSrc[x];
+ }
+ iSrc+=tmp.info.dwEffWidth;
+ }
+ return sum/(xmax-xmin)/(ymax-ymin);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * 2D linear filter
+ * \param kernel: convolving matrix, in row format.
+ * \param Ksize: size of the kernel.
+ * \param Kfactor: normalization constant.
+ * \param Koffset: bias.
+ * \verbatim Example: the "soften" filter uses this kernel:
+ 1 1 1
+ 1 8 1
+ 1 1 1
+ the function needs: kernel={1,1,1,1,8,1,1,1,1}; Ksize=3; Kfactor=16; Koffset=0; \endverbatim
+ * \return true if everything is ok
+ */
+bool CxImage::Filter(int32_t* kernel, int32_t Ksize, int32_t Kfactor, int32_t Koffset)
+{
+ if (!pDib) return false;
+
+ int32_t k2 = Ksize/2;
+ int32_t kmax= Ksize-k2;
+ int32_t r,g,b,i;
+ int32_t ksumcur,ksumtot;
+ RGBQUAD c;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ ksumtot = 0;
+ for(int32_t j=-k2;j<kmax;j++){
+ for(int32_t k=-k2;k<kmax;k++){
+ ksumtot += kernel[(j+k2)+Ksize*(k+k2)];
+ }
+ }
+
+ if ((head.biBitCount==8) && IsGrayScale())
+ {
+ uint8_t* cPtr;
+ uint8_t* cPtr2;
+ int32_t iCount;
+ int32_t iY, iY2, iY1;
+ cPtr = info.pImage;
+ cPtr2 = (uint8_t *)tmp.info.pImage;
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ iY1 = y*info.dwEffWidth+xmin;
+ for(int32_t x=xmin; x<xmax; x++, iY1++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ b=ksumcur=0;
+ iCount = 0;
+ iY2 = ((y-k2)*info.dwEffWidth);
+ for(int32_t j=-k2;j<kmax;j++, iY2+=info.dwEffWidth)
+ {
+ if (0>(y+j) || (y+j)>=head.biHeight) continue;
+ iY = iY2+x;
+ for(int32_t k=-k2;k<kmax;k++, iCount++)
+ {
+ if (0>(x+k) || (x+k)>=head.biWidth) continue;
+ i=kernel[iCount];
+ b += cPtr[iY+k] * i;
+ ksumcur += i;
+ }
+ }
+ if (Kfactor==0 || ksumcur==0){
+ cPtr2[iY1] = (uint8_t)min(255, max(0,(int32_t)(b + Koffset)));
+ } else if (ksumtot == ksumcur) {
+ cPtr2[iY1] = (uint8_t)min(255, max(0,(int32_t)(b/Kfactor + Koffset)));
+ } else {
+ cPtr2[iY1] = (uint8_t)min(255, max(0,(int32_t)((b*ksumtot)/(ksumcur*Kfactor) + Koffset)));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+ #if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+ #endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ r=b=g=ksumcur=0;
+ for(int32_t j=-k2;j<kmax;j++){
+ for(int32_t k=-k2;k<kmax;k++){
+ if (!IsInside(x+j,y+k)) continue;
+ c = BlindGetPixelColor(x+j,y+k);
+ i = kernel[(j+k2)+Ksize*(k+k2)];
+ r += c.rgbRed * i;
+ g += c.rgbGreen * i;
+ b += c.rgbBlue * i;
+ ksumcur += i;
+ }
+ }
+ if (Kfactor==0 || ksumcur==0){
+ c.rgbRed = (uint8_t)min(255, max(0,(int32_t)(r + Koffset)));
+ c.rgbGreen = (uint8_t)min(255, max(0,(int32_t)(g + Koffset)));
+ c.rgbBlue = (uint8_t)min(255, max(0,(int32_t)(b + Koffset)));
+ } else if (ksumtot == ksumcur) {
+ c.rgbRed = (uint8_t)min(255, max(0,(int32_t)(r/Kfactor + Koffset)));
+ c.rgbGreen = (uint8_t)min(255, max(0,(int32_t)(g/Kfactor + Koffset)));
+ c.rgbBlue = (uint8_t)min(255, max(0,(int32_t)(b/Kfactor + Koffset)));
+ } else {
+ c.rgbRed = (uint8_t)min(255, max(0,(int32_t)((r*ksumtot)/(ksumcur*Kfactor) + Koffset)));
+ c.rgbGreen = (uint8_t)min(255, max(0,(int32_t)((g*ksumtot)/(ksumcur*Kfactor) + Koffset)));
+ c.rgbBlue = (uint8_t)min(255, max(0,(int32_t)((b*ksumtot)/(ksumcur*Kfactor) + Koffset)));
+ }
+ tmp.BlindSetPixelColor(x,y,c);
+ }
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Enhance the dark areas of the image
+ * \param Ksize: size of the kernel.
+ * \return true if everything is ok
+ */
+bool CxImage::Erode(int32_t Ksize)
+{
+ if (!pDib) return false;
+
+ int32_t k2 = Ksize/2;
+ int32_t kmax= Ksize-k2;
+ uint8_t r,g,b;
+ RGBQUAD c;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ r=b=g=255;
+ for(int32_t j=-k2;j<kmax;j++){
+ for(int32_t k=-k2;k<kmax;k++){
+ if (!IsInside(x+j,y+k)) continue;
+ c = BlindGetPixelColor(x+j,y+k);
+ if (c.rgbRed < r) r=c.rgbRed;
+ if (c.rgbGreen < g) g=c.rgbGreen;
+ if (c.rgbBlue < b) b=c.rgbBlue;
+ }
+ }
+ c.rgbRed = r;
+ c.rgbGreen = g;
+ c.rgbBlue = b;
+ tmp.BlindSetPixelColor(x,y,c);
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Enhance the light areas of the image
+ * \param Ksize: size of the kernel.
+ * \return true if everything is ok
+ */
+bool CxImage::Dilate(int32_t Ksize)
+{
+ if (!pDib) return false;
+
+ int32_t k2 = Ksize/2;
+ int32_t kmax= Ksize-k2;
+ uint8_t r,g,b;
+ RGBQUAD c;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ r=b=g=0;
+ for(int32_t j=-k2;j<kmax;j++){
+ for(int32_t k=-k2;k<kmax;k++){
+ if (!IsInside(x+j,y+k)) continue;
+ c = BlindGetPixelColor(x+j,y+k);
+ if (c.rgbRed > r) r=c.rgbRed;
+ if (c.rgbGreen > g) g=c.rgbGreen;
+ if (c.rgbBlue > b) b=c.rgbBlue;
+ }
+ }
+ c.rgbRed = r;
+ c.rgbGreen = g;
+ c.rgbBlue = b;
+ tmp.BlindSetPixelColor(x,y,c);
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Enhance the variations between adjacent pixels.
+ * Similar results can be achieved using Filter(),
+ * but the algorithms are different both in Edge() and in Contour().
+ * \param Ksize: size of the kernel.
+ * \return true if everything is ok
+ */
+bool CxImage::Edge(int32_t Ksize)
+{
+ if (!pDib) return false;
+
+ int32_t k2 = Ksize/2;
+ int32_t kmax= Ksize-k2;
+ uint8_t r,g,b,rr,gg,bb;
+ RGBQUAD c;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ r=b=g=0;
+ rr=bb=gg=255;
+ for(int32_t j=-k2;j<kmax;j++){
+ for(int32_t k=-k2;k<kmax;k++){
+ if (!IsInside(x+j,y+k)) continue;
+ c = BlindGetPixelColor(x+j,y+k);
+ if (c.rgbRed > r) r=c.rgbRed;
+ if (c.rgbGreen > g) g=c.rgbGreen;
+ if (c.rgbBlue > b) b=c.rgbBlue;
+
+ if (c.rgbRed < rr) rr=c.rgbRed;
+ if (c.rgbGreen < gg) gg=c.rgbGreen;
+ if (c.rgbBlue < bb) bb=c.rgbBlue;
+ }
+ }
+ c.rgbRed = (uint8_t)(255-abs(r-rr));
+ c.rgbGreen = (uint8_t)(255-abs(g-gg));
+ c.rgbBlue = (uint8_t)(255-abs(b-bb));
+ tmp.BlindSetPixelColor(x,y,c);
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Blends two images
+ * \param imgsrc2: image to be mixed with this
+ * \param op: blending method; see ImageOpType
+ * \param lXOffset, lYOffset: image displacement
+ * \param bMixAlpha: if true and imgsrc2 has a valid alpha layer, it will be mixed in the destination image.
+ * \return true if everything is ok
+ * \author [Mwolski],[brunom]
+ */
+void CxImage::Mix(CxImage & imgsrc2, ImageOpType op, int32_t lXOffset, int32_t lYOffset, bool bMixAlpha)
+{
+ int32_t lWide = min(GetWidth(),imgsrc2.GetWidth()-lXOffset);
+ int32_t lHeight = min(GetHeight(),imgsrc2.GetHeight()-lYOffset);
+
+ bool bEditAlpha = false;
+
+#if CXIMAGE_SUPPORT_ALPHA
+ bEditAlpha = imgsrc2.AlphaIsValid() & bMixAlpha;
+ if (bEditAlpha && AlphaIsValid()==false){
+ AlphaCreate();
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ RGBQUAD rgbBackgrnd1 = GetTransColor();
+ RGBQUAD rgb1, rgb2, rgbDest;
+
+ for(int32_t lY=0;lY<lHeight;lY++)
+ {
+ info.nProgress = (int32_t)(100*lY/head.biHeight);
+ if (info.nEscape) break;
+
+ for(int32_t lX=0;lX<lWide;lX++)
+ {
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsInside(lX,lY) && imgsrc2.SelectionIsInside(lX+lXOffset,lY+lYOffset))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ rgb1 = GetPixelColor(lX,lY);
+ rgb2 = imgsrc2.GetPixelColor(lX+lXOffset,lY+lYOffset);
+ switch(op)
+ {
+ case OpAvg:
+ rgbDest.rgbBlue = (uint8_t)((rgb1.rgbBlue+rgb2.rgbBlue)/2);
+ rgbDest.rgbGreen = (uint8_t)((rgb1.rgbGreen+rgb2.rgbGreen)/2);
+ rgbDest.rgbRed = (uint8_t)((rgb1.rgbRed+rgb2.rgbRed)/2);
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)((rgb1.rgbReserved+rgb2.rgbReserved)/2);
+ break;
+ case OpAdd:
+ rgbDest.rgbBlue = (uint8_t)max(0,min(255,rgb1.rgbBlue+rgb2.rgbBlue));
+ rgbDest.rgbGreen = (uint8_t)max(0,min(255,rgb1.rgbGreen+rgb2.rgbGreen));
+ rgbDest.rgbRed = (uint8_t)max(0,min(255,rgb1.rgbRed+rgb2.rgbRed));
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)max(0,min(255,rgb1.rgbReserved+rgb2.rgbReserved));
+ break;
+ case OpSub:
+ rgbDest.rgbBlue = (uint8_t)max(0,min(255,rgb1.rgbBlue-rgb2.rgbBlue));
+ rgbDest.rgbGreen = (uint8_t)max(0,min(255,rgb1.rgbGreen-rgb2.rgbGreen));
+ rgbDest.rgbRed = (uint8_t)max(0,min(255,rgb1.rgbRed-rgb2.rgbRed));
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)max(0,min(255,rgb1.rgbReserved-rgb2.rgbReserved));
+ break;
+ case OpAnd:
+ rgbDest.rgbBlue = (uint8_t)(rgb1.rgbBlue&rgb2.rgbBlue);
+ rgbDest.rgbGreen = (uint8_t)(rgb1.rgbGreen&rgb2.rgbGreen);
+ rgbDest.rgbRed = (uint8_t)(rgb1.rgbRed&rgb2.rgbRed);
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)(rgb1.rgbReserved&rgb2.rgbReserved);
+ break;
+ case OpXor:
+ rgbDest.rgbBlue = (uint8_t)(rgb1.rgbBlue^rgb2.rgbBlue);
+ rgbDest.rgbGreen = (uint8_t)(rgb1.rgbGreen^rgb2.rgbGreen);
+ rgbDest.rgbRed = (uint8_t)(rgb1.rgbRed^rgb2.rgbRed);
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)(rgb1.rgbReserved^rgb2.rgbReserved);
+ break;
+ case OpOr:
+ rgbDest.rgbBlue = (uint8_t)(rgb1.rgbBlue|rgb2.rgbBlue);
+ rgbDest.rgbGreen = (uint8_t)(rgb1.rgbGreen|rgb2.rgbGreen);
+ rgbDest.rgbRed = (uint8_t)(rgb1.rgbRed|rgb2.rgbRed);
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)(rgb1.rgbReserved|rgb2.rgbReserved);
+ break;
+ case OpMask:
+ if(rgb2.rgbBlue==0 && rgb2.rgbGreen==0 && rgb2.rgbRed==0)
+ rgbDest = rgbBackgrnd1;
+ else
+ rgbDest = rgb1;
+ break;
+ case OpSrcCopy:
+ if(IsTransparent(lX,lY))
+ rgbDest = rgb2;
+ else // copy straight over
+ rgbDest = rgb1;
+ break;
+ case OpDstCopy:
+ if(imgsrc2.IsTransparent(lX+lXOffset,lY+lYOffset))
+ rgbDest = rgb1;
+ else // copy straight over
+ rgbDest = rgb2;
+ break;
+ case OpScreen:
+ {
+ uint8_t a,a1;
+
+ if (imgsrc2.IsTransparent(lX+lXOffset,lY+lYOffset)){
+ a=0;
+#if CXIMAGE_SUPPORT_ALPHA
+ } else if (imgsrc2.AlphaIsValid()){
+ a=imgsrc2.AlphaGet(lX+lXOffset,lY+lYOffset);
+ a =(uint8_t)((a*imgsrc2.info.nAlphaMax)/255);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ } else {
+ a=255;
+ }
+
+ if (a==0){ //transparent
+ rgbDest = rgb1;
+ } else if (a==255){ //opaque
+ rgbDest = rgb2;
+ } else { //blend
+ a1 = (uint8_t)~a;
+ rgbDest.rgbBlue = (uint8_t)((rgb1.rgbBlue*a1+rgb2.rgbBlue*a)/255);
+ rgbDest.rgbGreen = (uint8_t)((rgb1.rgbGreen*a1+rgb2.rgbGreen*a)/255);
+ rgbDest.rgbRed = (uint8_t)((rgb1.rgbRed*a1+rgb2.rgbRed*a)/255);
+ }
+
+ if (bEditAlpha) rgbDest.rgbReserved = (uint8_t)((rgb1.rgbReserved*a)/255);
+ }
+ break;
+ case OpSrcBlend:
+ if(IsTransparent(lX,lY))
+ rgbDest = rgb2;
+ else
+ {
+ int32_t lBDiff = abs(rgb1.rgbBlue - rgbBackgrnd1.rgbBlue);
+ int32_t lGDiff = abs(rgb1.rgbGreen - rgbBackgrnd1.rgbGreen);
+ int32_t lRDiff = abs(rgb1.rgbRed - rgbBackgrnd1.rgbRed);
+
+ double lAverage = (lBDiff+lGDiff+lRDiff)/3;
+ double lThresh = 16;
+ double dLarge = lAverage/lThresh;
+ double dSmall = (lThresh-lAverage)/lThresh;
+ double dSmallAmt = dSmall*((double)rgb2.rgbBlue);
+
+ if( lAverage < lThresh+1){
+ rgbDest.rgbBlue = (uint8_t)max(0,min(255,(int32_t)(dLarge*((double)rgb1.rgbBlue) +
+ dSmallAmt)));
+ rgbDest.rgbGreen = (uint8_t)max(0,min(255,(int32_t)(dLarge*((double)rgb1.rgbGreen) +
+ dSmallAmt)));
+ rgbDest.rgbRed = (uint8_t)max(0,min(255,(int32_t)(dLarge*((double)rgb1.rgbRed) +
+ dSmallAmt)));
+ }
+ else
+ rgbDest = rgb1;
+ }
+ break;
+ case OpBlendAlpha: //[brunom]
+ if(rgb2.rgbReserved != 0)
+ {
+ // The lower value is almost transparent, or the overlying
+ // almost transparent can not directly overlying the value taken
+ if( (rgb1.rgbReserved < 5) || (rgb2.rgbReserved > 250) ){
+ rgbDest = rgb2;
+ } else {
+ // Alpha Blending with associative calculation merge
+ // (http://en.wikipedia.org/wiki/Alpha_compositing)
+ int32_t a0,a1,a2;
+ // Transparency of the superimposed image
+ a2 = rgb2.rgbReserved;
+ // Calculation transparency of the underlying image
+ a1 = (rgb1.rgbReserved * (255 - a2)) >> 8;
+ // total transparency of the new pixel
+ a0 = a2 + a1;
+ // New transparency assume (a0 == 0 is the restriction s.o. (range 5-250) intercepted)
+ if (bEditAlpha) rgbDest.rgbReserved = a0;
+ // each color channel to calculate
+ rgbDest.rgbBlue = (BYTE)((rgb2.rgbBlue * a2 + a1 * rgb1.rgbBlue )/a0);
+ rgbDest.rgbGreen = (BYTE)((rgb2.rgbGreen * a2 + a1 * rgb1.rgbGreen)/a0);
+ rgbDest.rgbRed = (BYTE)((rgb2.rgbRed * a2 + a1 * rgb1.rgbRed )/a0);
+ }
+ } else {
+ rgbDest = rgb1;
+ rgbDest.rgbReserved = 0;
+ }
+ break;
+ default:
+ return;
+ }
+ SetPixelColor(lX,lY,rgbDest,bEditAlpha);
+ }
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+// thanks to Kenneth Ballard
+void CxImage::MixFrom(CxImage & imagesrc2, int32_t lXOffset, int32_t lYOffset)
+{
+ int32_t width = imagesrc2.GetWidth();
+ int32_t height = imagesrc2.GetHeight();
+
+ int32_t x, y;
+
+ if (imagesrc2.IsTransparent()) {
+ for(x = 0; x < width; x++) {
+ for(y = 0; y < height; y++) {
+ if(!imagesrc2.IsTransparent(x,y)){
+ SetPixelColor(x + lXOffset, y + lYOffset, imagesrc2.BlindGetPixelColor(x, y));
+ }
+ }
+ }
+ } else { //no transparency so just set it <Matt>
+ for(x = 0; x < width; x++) {
+ for(y = 0; y < height; y++) {
+ SetPixelColor(x + lXOffset, y + lYOffset, imagesrc2.BlindGetPixelColor(x, y));
+ }
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adjusts separately the red, green, and blue values in the image.
+ * \param r, g, b: can be from -255 to +255.
+ * \return true if everything is ok
+ */
+bool CxImage::ShiftRGB(int32_t r, int32_t g, int32_t b)
+{
+ if (!pDib) return false;
+ RGBQUAD color;
+ if (head.biClrUsed==0){
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ color = BlindGetPixelColor(x,y);
+ color.rgbRed = (uint8_t)max(0,min(255,(int32_t)(color.rgbRed + r)));
+ color.rgbGreen = (uint8_t)max(0,min(255,(int32_t)(color.rgbGreen + g)));
+ color.rgbBlue = (uint8_t)max(0,min(255,(int32_t)(color.rgbBlue + b)));
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+ } else {
+ for(uint32_t j=0; j<head.biClrUsed; j++){
+ color = GetPaletteColor((uint8_t)j);
+ color.rgbRed = (uint8_t)max(0,min(255,(int32_t)(color.rgbRed + r)));
+ color.rgbGreen = (uint8_t)max(0,min(255,(int32_t)(color.rgbGreen + g)));
+ color.rgbBlue = (uint8_t)max(0,min(255,(int32_t)(color.rgbBlue + b)));
+ SetPaletteColor((uint8_t)j,color);
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adjusts the color balance of the image
+ * \param gamma can be from 0.1 to 5.
+ * \return true if everything is ok
+ * \sa GammaRGB
+ */
+bool CxImage::Gamma(float gamma)
+{
+ if (!pDib) return false;
+
+ if (gamma <= 0.0f) return false;
+
+ double dinvgamma = 1/gamma;
+ double dMax = pow(255.0, dinvgamma) / 255.0;
+
+ uint8_t cTable[256]; //<nipper>
+ for (int32_t i=0;i<256;i++) {
+ cTable[i] = (uint8_t)max(0,min(255,(int32_t)( pow((double)i, dinvgamma) / dMax)));
+ }
+
+ return Lut(cTable);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adjusts the color balance indipendent for each color channel
+ * \param gammaR, gammaG, gammaB can be from 0.1 to 5.
+ * \return true if everything is ok
+ * \sa Gamma
+ */
+bool CxImage::GammaRGB(float gammaR, float gammaG, float gammaB)
+{
+ if (!pDib) return false;
+
+ if (gammaR <= 0.0f) return false;
+ if (gammaG <= 0.0f) return false;
+ if (gammaB <= 0.0f) return false;
+
+ double dinvgamma, dMax;
+ int32_t i;
+
+ dinvgamma = 1/gammaR;
+ dMax = pow(255.0, dinvgamma) / 255.0;
+ uint8_t cTableR[256];
+ for (i=0;i<256;i++) {
+ cTableR[i] = (uint8_t)max(0,min(255,(int32_t)( pow((double)i, dinvgamma) / dMax)));
+ }
+
+ dinvgamma = 1/gammaG;
+ dMax = pow(255.0, dinvgamma) / 255.0;
+ uint8_t cTableG[256];
+ for (i=0;i<256;i++) {
+ cTableG[i] = (uint8_t)max(0,min(255,(int32_t)( pow((double)i, dinvgamma) / dMax)));
+ }
+
+ dinvgamma = 1/gammaB;
+ dMax = pow(255.0, dinvgamma) / 255.0;
+ uint8_t cTableB[256];
+ for (i=0;i<256;i++) {
+ cTableB[i] = (uint8_t)max(0,min(255,(int32_t)( pow((double)i, dinvgamma) / dMax)));
+ }
+
+ return Lut(cTableR, cTableG, cTableB);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+//#if !defined (_WIN32_WCE)
+/**
+ * Adjusts the intensity of each pixel to the median intensity of its surrounding pixels.
+ * \param Ksize: size of the kernel.
+ * \return true if everything is ok
+ */
+bool CxImage::Median(int32_t Ksize)
+{
+ if (!pDib) return false;
+
+ int32_t k2 = Ksize/2;
+ int32_t kmax= Ksize-k2;
+ int32_t i,j,k;
+
+ RGBQUAD* kernel = (RGBQUAD*)malloc(Ksize*Ksize*sizeof(RGBQUAD));
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ for(j=-k2, i=0;j<kmax;j++)
+ for(k=-k2;k<kmax;k++)
+ if (IsInside(x+j,y+k))
+ kernel[i++]=BlindGetPixelColor(x+j,y+k);
+
+ qsort(kernel, i, sizeof(RGBQUAD), CompareColors);
+ tmp.SetPixelColor(x,y,kernel[i/2]);
+ }
+ }
+ }
+ free(kernel);
+ Transfer(tmp);
+ return true;
+}
+//#endif //_WIN32_WCE
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds an uniform noise to the image
+ * \param level: can be from 0 (no noise) to 255 (lot of noise).
+ * \return true if everything is ok
+ */
+bool CxImage::Noise(int32_t level)
+{
+ if (!pDib) return false;
+ RGBQUAD color;
+
+ int32_t xmin,xmax,ymin,ymax,n;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin)); //<zhanghk><Anatoly Ivasyuk>
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ color = BlindGetPixelColor(x,y);
+ n=(int32_t)((rand()/(float)RAND_MAX - 0.5)*level);
+ color.rgbRed = (uint8_t)max(0,min(255,(int32_t)(color.rgbRed + n)));
+ n=(int32_t)((rand()/(float)RAND_MAX - 0.5)*level);
+ color.rgbGreen = (uint8_t)max(0,min(255,(int32_t)(color.rgbGreen + n)));
+ n=(int32_t)((rand()/(float)RAND_MAX - 0.5)*level);
+ color.rgbBlue = (uint8_t)max(0,min(255,(int32_t)(color.rgbBlue + n)));
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Computes the bidimensional FFT or DFT of the image.
+ * - The images are processed as grayscale
+ * - If the dimensions of the image are a power of, 2 the FFT is performed automatically.
+ * - If dstReal and/or dstImag are NULL, the resulting images replaces the original(s).
+ * - Note: with 8 bits there is a HUGE loss in the dynamics. The function tries
+ * to keep an acceptable SNR, but 8bit = 48dB...
+ *
+ * \param srcReal, srcImag: source images: One can be NULL, but not both
+ * \param dstReal, dstImag: destination images. Can be NULL.
+ * \param direction: 1 = forward, -1 = inverse.
+ * \param bForceFFT: if true, the images are resampled to make the dimensions a power of 2.
+ * \param bMagnitude: if true, the real part returns the magnitude, the imaginary part returns the phase
+ * \return true if everything is ok
+ */
+bool CxImage::FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag,
+ int32_t direction, bool bForceFFT, bool bMagnitude)
+{
+ //check if there is something to convert
+ if (srcReal==NULL && srcImag==NULL) return false;
+
+ int32_t w,h;
+ //get width and height
+ if (srcReal) {
+ w=srcReal->GetWidth();
+ h=srcReal->GetHeight();
+ } else {
+ w=srcImag->GetWidth();
+ h=srcImag->GetHeight();
+ }
+
+ bool bXpow2 = IsPowerof2(w);
+ bool bYpow2 = IsPowerof2(h);
+ //if bForceFFT, width AND height must be powers of 2
+ if (bForceFFT && !(bXpow2 && bYpow2)) {
+ int32_t i;
+
+ i=0;
+ while((1<<i)<w) i++;
+ w=1<<i;
+ bXpow2=true;
+
+ i=0;
+ while((1<<i)<h) i++;
+ h=1<<i;
+ bYpow2=true;
+ }
+
+ // I/O images for FFT
+ CxImage *tmpReal,*tmpImag;
+
+ // select output
+ tmpReal = (dstReal) ? dstReal : srcReal;
+ tmpImag = (dstImag) ? dstImag : srcImag;
+
+ // src!=dst -> copy the image
+ if (srcReal && dstReal) tmpReal->Copy(*srcReal,true,false,false);
+ if (srcImag && dstImag) tmpImag->Copy(*srcImag,true,false,false);
+
+ // dst&&src are empty -> create new one, else turn to GrayScale
+ if (srcReal==0 && dstReal==0){
+ tmpReal = new CxImage(w,h,8);
+ tmpReal->Clear(0);
+ tmpReal->SetGrayPalette();
+ } else {
+ if (!tmpReal->IsGrayScale()) tmpReal->GrayScale();
+ }
+ if (srcImag==0 && dstImag==0){
+ tmpImag = new CxImage(w,h,8);
+ tmpImag->Clear(0);
+ tmpImag->SetGrayPalette();
+ } else {
+ if (!tmpImag->IsGrayScale()) tmpImag->GrayScale();
+ }
+
+ if (!(tmpReal->IsValid() && tmpImag->IsValid())){
+ if (srcReal==0 && dstReal==0) delete tmpReal;
+ if (srcImag==0 && dstImag==0) delete tmpImag;
+ return false;
+ }
+
+ //resample for FFT, if necessary
+ tmpReal->Resample(w,h,0);
+ tmpImag->Resample(w,h,0);
+
+ //ok, here we have 2 (w x h), grayscale images ready for a FFT
+
+ double* real;
+ double* imag;
+ int32_t j,k,m;
+
+ _complex **grid;
+ //double mean = tmpReal->Mean();
+ /* Allocate memory for the grid */
+ grid = (_complex **)malloc(w * sizeof(_complex));
+ for (k=0;k<w;k++) {
+ grid[k] = (_complex *)malloc(h * sizeof(_complex));
+ }
+ for (j=0;j<h;j++) {
+ for (k=0;k<w;k++) {
+ grid[k][j].x = tmpReal->GetPixelIndex(k,j)-128;
+ grid[k][j].y = tmpImag->GetPixelIndex(k,j)-128;
+ }
+ }
+
+ //DFT buffers
+ double *real2,*imag2;
+ real2 = (double*)malloc(max(w,h) * sizeof(double));
+ imag2 = (double*)malloc(max(w,h) * sizeof(double));
+
+ /* Transform the rows */
+ real = (double *)malloc(w * sizeof(double));
+ imag = (double *)malloc(w * sizeof(double));
+
+ m=0;
+ while((1<<m)<w) m++;
+
+ for (j=0;j<h;j++) {
+ for (k=0;k<w;k++) {
+ real[k] = grid[k][j].x;
+ imag[k] = grid[k][j].y;
+ }
+
+ if (bXpow2) FFT(direction,m,real,imag);
+ else DFT(direction,w,real,imag,real2,imag2);
+
+ for (k=0;k<w;k++) {
+ grid[k][j].x = real[k];
+ grid[k][j].y = imag[k];
+ }
+ }
+ free(real);
+ free(imag);
+
+ /* Transform the columns */
+ real = (double *)malloc(h * sizeof(double));
+ imag = (double *)malloc(h * sizeof(double));
+
+ m=0;
+ while((1<<m)<h) m++;
+
+ for (k=0;k<w;k++) {
+ for (j=0;j<h;j++) {
+ real[j] = grid[k][j].x;
+ imag[j] = grid[k][j].y;
+ }
+
+ if (bYpow2) FFT(direction,m,real,imag);
+ else DFT(direction,h,real,imag,real2,imag2);
+
+ for (j=0;j<h;j++) {
+ grid[k][j].x = real[j];
+ grid[k][j].y = imag[j];
+ }
+ }
+ free(real);
+ free(imag);
+
+ free(real2);
+ free(imag2);
+
+ /* converting from double to byte, there is a HUGE loss in the dynamics
+ "nn" tries to keep an acceptable SNR, but 8bit=48dB: don't ask more */
+ double nn=pow((double)2,(double)log((double)max(w,h))/(double)log((double)2)-4);
+ //reversed gain for reversed transform
+ if (direction==-1) nn=1/nn;
+ //bMagnitude : just to see it on the screen
+ if (bMagnitude) nn*=4;
+
+ for (j=0;j<h;j++) {
+ for (k=0;k<w;k++) {
+ if (bMagnitude){
+ tmpReal->SetPixelIndex(k,j,(uint8_t)max(0,min(255,(nn*(3+log(_cabs(grid[k][j])))))));
+ if (grid[k][j].x==0){
+ tmpImag->SetPixelIndex(k,j,(uint8_t)max(0,min(255,(128+(atan(grid[k][j].y/0.0000000001)*nn)))));
+ } else {
+ tmpImag->SetPixelIndex(k,j,(uint8_t)max(0,min(255,(128+(atan(grid[k][j].y/grid[k][j].x)*nn)))));
+ }
+ } else {
+ tmpReal->SetPixelIndex(k,j,(uint8_t)max(0,min(255,(128 + grid[k][j].x*nn))));
+ tmpImag->SetPixelIndex(k,j,(uint8_t)max(0,min(255,(128 + grid[k][j].y*nn))));
+ }
+ }
+ }
+
+ for (k=0;k<w;k++) free (grid[k]);
+ free (grid);
+
+ if (srcReal==0 && dstReal==0) delete tmpReal;
+ if (srcImag==0 && dstImag==0) delete tmpImag;
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::IsPowerof2(int32_t x)
+{
+ int32_t i=0;
+ while ((1<<i)<x) i++;
+ if (x==(1<<i)) return true;
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ This computes an in-place complex-to-complex FFT
+ x and y are the real and imaginary arrays of n=2^m points.
+ o(n)=n*log2(n)
+ dir = 1 gives forward transform
+ dir = -1 gives reverse transform
+ Written by Paul Bourke, July 1998
+ FFT algorithm by Cooley and Tukey, 1965
+*/
+bool CxImage::FFT(int32_t dir,int32_t m,double *x,double *y)
+{
+ int32_t nn,i,i1,j,k,i2,l,l1,l2;
+ double c1,c2,tx,ty,t1,t2,u1,u2,z;
+
+ /* Calculate the number of points */
+ nn = 1<<m;
+
+ /* Do the bit reversal */
+ i2 = nn >> 1;
+ j = 0;
+ for (i=0;i<nn-1;i++) {
+ if (i < j) {
+ tx = x[i];
+ ty = y[i];
+ x[i] = x[j];
+ y[i] = y[j];
+ x[j] = tx;
+ y[j] = ty;
+ }
+ k = i2;
+ while (k <= j) {
+ j -= k;
+ k >>= 1;
+ }
+ j += k;
+ }
+
+ /* Compute the FFT */
+ c1 = -1.0;
+ c2 = 0.0;
+ l2 = 1;
+ for (l=0;l<m;l++) {
+ l1 = l2;
+ l2 <<= 1;
+ u1 = 1.0;
+ u2 = 0.0;
+ for (j=0;j<l1;j++) {
+ for (i=j;i<nn;i+=l2) {
+ i1 = i + l1;
+ t1 = u1 * x[i1] - u2 * y[i1];
+ t2 = u1 * y[i1] + u2 * x[i1];
+ x[i1] = x[i] - t1;
+ y[i1] = y[i] - t2;
+ x[i] += t1;
+ y[i] += t2;
+ }
+ z = u1 * c1 - u2 * c2;
+ u2 = u1 * c2 + u2 * c1;
+ u1 = z;
+ }
+ c2 = sqrt((1.0 - c1) / 2.0);
+ if (dir == 1)
+ c2 = -c2;
+ c1 = sqrt((1.0 + c1) / 2.0);
+ }
+
+ /* Scaling for forward transform */
+ if (dir == 1) {
+ for (i=0;i<nn;i++) {
+ x[i] /= (double)nn;
+ y[i] /= (double)nn;
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ Direct fourier transform o(n)=n^2
+ Written by Paul Bourke, July 1998
+*/
+bool CxImage::DFT(int32_t dir,int32_t m,double *x1,double *y1,double *x2,double *y2)
+{
+ int32_t i,k;
+ double arg;
+ double cosarg,sinarg;
+
+ for (i=0;i<m;i++) {
+ x2[i] = 0;
+ y2[i] = 0;
+ arg = - dir * 2.0 * PI * i / (double)m;
+ for (k=0;k<m;k++) {
+ cosarg = cos(k * arg);
+ sinarg = sin(k * arg);
+ x2[i] += (x1[k] * cosarg - y1[k] * sinarg);
+ y2[i] += (x1[k] * sinarg + y1[k] * cosarg);
+ }
+ }
+
+ /* Copy the data back */
+ if (dir == 1) {
+ for (i=0;i<m;i++) {
+ x1[i] = x2[i] / m;
+ y1[i] = y2[i] / m;
+ }
+ } else {
+ for (i=0;i<m;i++) {
+ x1[i] = x2[i];
+ y1[i] = y2[i];
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Combines different color components into a single image
+ * \param r,g,b: color channels
+ * \param a: alpha layer, can be NULL
+ * \param colorspace: 0 = RGB, 1 = HSL, 2 = YUV, 3 = YIQ, 4 = XYZ
+ * \return true if everything is ok
+ */
+bool CxImage::Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, int32_t colorspace)
+{
+ if (r==0 || g==0 || b==0) return false;
+
+ int32_t w = r->GetWidth();
+ int32_t h = r->GetHeight();
+
+ Create(w,h,24);
+
+ g->Resample(w,h);
+ b->Resample(w,h);
+
+ if (a) {
+ a->Resample(w,h);
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+
+ RGBQUAD c;
+ for (int32_t y=0;y<h;y++){
+ info.nProgress = (int32_t)(100*y/h); //<Anatoly Ivasyuk>
+ for (int32_t x=0;x<w;x++){
+ c.rgbRed=r->GetPixelIndex(x,y);
+ c.rgbGreen=g->GetPixelIndex(x,y);
+ c.rgbBlue=b->GetPixelIndex(x,y);
+ switch (colorspace){
+ case 1:
+ BlindSetPixelColor(x,y,HSLtoRGB(c));
+ break;
+ case 2:
+ BlindSetPixelColor(x,y,YUVtoRGB(c));
+ break;
+ case 3:
+ BlindSetPixelColor(x,y,YIQtoRGB(c));
+ break;
+ case 4:
+ BlindSetPixelColor(x,y,XYZtoRGB(c));
+ break;
+ default:
+ BlindSetPixelColor(x,y,c);
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ if (a) AlphaSet(x,y,a->GetPixelIndex(x,y));
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Smart blurring to remove small defects, dithering or artifacts.
+ * \param radius: normally between 0.01 and 0.5
+ * \param niterations: should be trimmed with radius, to avoid blurring should be (radius*niterations)<1
+ * \param colorspace: 0 = RGB, 1 = HSL, 2 = YUV, 3 = YIQ, 4 = XYZ
+ * \return true if everything is ok
+ */
+bool CxImage::Repair(float radius, int32_t niterations, int32_t colorspace)
+{
+ if (!IsValid()) return false;
+
+ int32_t w = GetWidth();
+ int32_t h = GetHeight();
+
+ CxImage r,g,b;
+
+ r.Create(w,h,8);
+ g.Create(w,h,8);
+ b.Create(w,h,8);
+
+ switch (colorspace){
+ case 1:
+ SplitHSL(&r,&g,&b);
+ break;
+ case 2:
+ SplitYUV(&r,&g,&b);
+ break;
+ case 3:
+ SplitYIQ(&r,&g,&b);
+ break;
+ case 4:
+ SplitXYZ(&r,&g,&b);
+ break;
+ default:
+ SplitRGB(&r,&g,&b);
+ }
+
+ for (int32_t i=0; i<niterations; i++){
+ RepairChannel(&r,radius);
+ RepairChannel(&g,radius);
+ RepairChannel(&b,radius);
+ }
+
+ CxImage* a=NULL;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){
+ a = new CxImage();
+ AlphaSplit(a);
+ }
+#endif
+
+ Combine(&r,&g,&b,a,colorspace);
+
+ delete a;
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::RepairChannel(CxImage *ch, float radius)
+{
+ if (ch==NULL) return false;
+
+ CxImage tmp(*ch);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t w = ch->GetWidth()-1;
+ int32_t h = ch->GetHeight()-1;
+
+ double correction,ix,iy,ixx,ixy,iyy;
+ int32_t x,y,xy0,xp1,xm1,yp1,ym1;
+
+ for(x=1; x<w; x++){
+ for(y=1; y<h; y++){
+
+ xy0 = ch->BlindGetPixelIndex(x,y);
+ xm1 = ch->BlindGetPixelIndex(x-1,y);
+ xp1 = ch->BlindGetPixelIndex(x+1,y);
+ ym1 = ch->BlindGetPixelIndex(x,y-1);
+ yp1 = ch->BlindGetPixelIndex(x,y+1);
+
+ ix= (xp1-xm1)/2.0;
+ iy= (yp1-ym1)/2.0;
+ ixx= xp1 - 2.0 * xy0 + xm1;
+ iyy= yp1 - 2.0 * xy0 + ym1;
+ ixy=(ch->BlindGetPixelIndex(x+1,y+1) + ch->BlindGetPixelIndex(x-1,y-1) -
+ ch->BlindGetPixelIndex(x-1,y+1) - ch->BlindGetPixelIndex(x+1,y-1))/4.0;
+
+ correction = ((1.0+iy*iy)*ixx - ix*iy*ixy + (1.0+ix*ix)*iyy)/(1.0+ix*ix+iy*iy);
+
+ tmp.BlindSetPixelIndex(x,y,(uint8_t)min(255,max(0,(xy0 + radius * correction + 0.5))));
+ }
+ }
+
+ for (x=0;x<=w;x++){
+ for(y=0; y<=h; y+=h){
+ xy0 = ch->BlindGetPixelIndex(x,y);
+ xm1 = ch->GetPixelIndex(x-1,y);
+ xp1 = ch->GetPixelIndex(x+1,y);
+ ym1 = ch->GetPixelIndex(x,y-1);
+ yp1 = ch->GetPixelIndex(x,y+1);
+
+ ix= (xp1-xm1)/2.0;
+ iy= (yp1-ym1)/2.0;
+ ixx= xp1 - 2.0 * xy0 + xm1;
+ iyy= yp1 - 2.0 * xy0 + ym1;
+ ixy=(ch->GetPixelIndex(x+1,y+1) + ch->GetPixelIndex(x-1,y-1) -
+ ch->GetPixelIndex(x-1,y+1) - ch->GetPixelIndex(x+1,y-1))/4.0;
+
+ correction = ((1.0+iy*iy)*ixx - ix*iy*ixy + (1.0+ix*ix)*iyy)/(1.0+ix*ix+iy*iy);
+
+ tmp.BlindSetPixelIndex(x,y,(uint8_t)min(255,max(0,(xy0 + radius * correction + 0.5))));
+ }
+ }
+ for (x=0;x<=w;x+=w){
+ for (y=0;y<=h;y++){
+ xy0 = ch->BlindGetPixelIndex(x,y);
+ xm1 = ch->GetPixelIndex(x-1,y);
+ xp1 = ch->GetPixelIndex(x+1,y);
+ ym1 = ch->GetPixelIndex(x,y-1);
+ yp1 = ch->GetPixelIndex(x,y+1);
+
+ ix= (xp1-xm1)/2.0;
+ iy= (yp1-ym1)/2.0;
+ ixx= xp1 - 2.0 * xy0 + xm1;
+ iyy= yp1 - 2.0 * xy0 + ym1;
+ ixy=(ch->GetPixelIndex(x+1,y+1) + ch->GetPixelIndex(x-1,y-1) -
+ ch->GetPixelIndex(x-1,y+1) - ch->GetPixelIndex(x+1,y-1))/4.0;
+
+ correction = ((1.0+iy*iy)*ixx - ix*iy*ixy + (1.0+ix*ix)*iyy)/(1.0+ix*ix+iy*iy);
+
+ tmp.BlindSetPixelIndex(x,y,(uint8_t)min(255,max(0,(xy0 + radius * correction + 0.5))));
+ }
+ }
+
+ ch->Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Enhance the variations between adjacent pixels.
+ * Similar results can be achieved using Filter(),
+ * but the algorithms are different both in Edge() and in Contour().
+ * \return true if everything is ok
+ */
+bool CxImage::Contour()
+{
+ if (!pDib) return false;
+
+ int32_t Ksize = 3;
+ int32_t k2 = Ksize/2;
+ int32_t kmax= Ksize-k2;
+ int32_t i,j,k;
+ uint8_t maxr,maxg,maxb;
+ RGBQUAD pix1,pix2;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ pix1 = BlindGetPixelColor(x,y);
+ maxr=maxg=maxb=0;
+ for(j=-k2, i=0;j<kmax;j++){
+ for(k=-k2;k<kmax;k++, i++){
+ if (!IsInside(x+j,y+k)) continue;
+ pix2 = BlindGetPixelColor(x+j,y+k);
+ if ((pix2.rgbBlue-pix1.rgbBlue)>maxb) maxb = pix2.rgbBlue;
+ if ((pix2.rgbGreen-pix1.rgbGreen)>maxg) maxg = pix2.rgbGreen;
+ if ((pix2.rgbRed-pix1.rgbRed)>maxr) maxr = pix2.rgbRed;
+ }
+ }
+ pix1.rgbBlue=(uint8_t)(255-maxb);
+ pix1.rgbGreen=(uint8_t)(255-maxg);
+ pix1.rgbRed=(uint8_t)(255-maxr);
+ tmp.BlindSetPixelColor(x,y,pix1);
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds a random offset to each pixel in the image
+ * \param radius: maximum pixel displacement
+ * \return true if everything is ok
+ */
+bool CxImage::Jitter(int32_t radius)
+{
+ if (!pDib) return false;
+
+ int32_t nx,ny;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ nx=x+(int32_t)((rand()/(float)RAND_MAX - 0.5)*(radius*2));
+ ny=y+(int32_t)((rand()/(float)RAND_MAX - 0.5)*(radius*2));
+ if (!IsInside(nx,ny)) {
+ nx=x;
+ ny=y;
+ }
+ if (head.biClrUsed==0){
+ tmp.BlindSetPixelColor(x,y,BlindGetPixelColor(nx,ny));
+ } else {
+ tmp.BlindSetPixelIndex(x,y,BlindGetPixelIndex(nx,ny));
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaSet(x,y,AlphaGet(nx,ny));
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * generates a 1-D convolution matrix to be used for each pass of
+ * a two-pass gaussian blur. Returns the length of the matrix.
+ * \author [nipper]
+ */
+int32_t CxImage::gen_convolve_matrix (float radius, float **cmatrix_p)
+{
+ int32_t matrix_length;
+ int32_t matrix_midpoint;
+ float* cmatrix;
+ int32_t i,j;
+ float std_dev;
+ float sum;
+
+ /* we want to generate a matrix that goes out a certain radius
+ * from the center, so we have to go out ceil(rad-0.5) pixels,
+ * inlcuding the center pixel. Of course, that's only in one direction,
+ * so we have to go the same amount in the other direction, but not count
+ * the center pixel again. So we double the previous result and subtract
+ * one.
+ * The radius parameter that is passed to this function is used as
+ * the standard deviation, and the radius of effect is the
+ * standard deviation * 2. It's a little confusing.
+ * <DP> modified scaling, so that matrix_lenght = 1+2*radius parameter
+ */
+ radius = (float)fabs(0.5*radius) + 0.25f;
+
+ std_dev = radius;
+ radius = std_dev * 2;
+
+ /* go out 'radius' in each direction */
+ matrix_length = int32_t (2 * ceil(radius-0.5) + 1);
+ if (matrix_length <= 0) matrix_length = 1;
+ matrix_midpoint = matrix_length/2 + 1;
+ *cmatrix_p = new float[matrix_length];
+ cmatrix = *cmatrix_p;
+
+ /* Now we fill the matrix by doing a numeric integration approximation
+ * from -2*std_dev to 2*std_dev, sampling 50 points per pixel.
+ * We do the bottom half, mirror it to the top half, then compute the
+ * center point. Otherwise asymmetric quantization errors will occur.
+ * The formula to integrate is e^-(x^2/2s^2).
+ */
+
+ /* first we do the top (right) half of matrix */
+ for (i = matrix_length/2 + 1; i < matrix_length; i++)
+ {
+ float base_x = i - (float)floor((float)(matrix_length/2)) - 0.5f;
+ sum = 0;
+ for (j = 1; j <= 50; j++)
+ {
+ if ( base_x+0.02*j <= radius )
+ sum += (float)exp (-(base_x+0.02*j)*(base_x+0.02*j) /
+ (2*std_dev*std_dev));
+ }
+ cmatrix[i] = sum/50;
+ }
+
+ /* mirror the thing to the bottom half */
+ for (i=0; i<=matrix_length/2; i++) {
+ cmatrix[i] = cmatrix[matrix_length-1-i];
+ }
+
+ /* find center val -- calculate an odd number of quanta to make it symmetric,
+ * even if the center point is weighted slightly higher than others. */
+ sum = 0;
+ for (j=0; j<=50; j++)
+ {
+ sum += (float)exp (-(0.5+0.02*j)*(0.5+0.02*j) /
+ (2*std_dev*std_dev));
+ }
+ cmatrix[matrix_length/2] = sum/51;
+
+ /* normalize the distribution by scaling the total sum to one */
+ sum=0;
+ for (i=0; i<matrix_length; i++) sum += cmatrix[i];
+ for (i=0; i<matrix_length; i++) cmatrix[i] = cmatrix[i] / sum;
+
+ return matrix_length;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * generates a lookup table for every possible product of 0-255 and
+ * each value in the convolution matrix. The returned array is
+ * indexed first by matrix position, then by input multiplicand (?)
+ * value.
+ * \author [nipper]
+ */
+float* CxImage::gen_lookup_table (float *cmatrix, int32_t cmatrix_length)
+{
+ float* lookup_table = new float[cmatrix_length * 256];
+ float* lookup_table_p = lookup_table;
+ float* cmatrix_p = cmatrix;
+
+ for (int32_t i=0; i<cmatrix_length; i++)
+ {
+ for (int32_t j=0; j<256; j++)
+ {
+ *(lookup_table_p++) = *cmatrix_p * (float)j;
+ }
+ cmatrix_p++;
+ }
+
+ return lookup_table;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * this function is written as if it is blurring a column at a time,
+ * even though it can operate on rows, too. There is no difference
+ * in the processing of the lines, at least to the blur_line function.
+ * \author [nipper]
+ */
+void CxImage::blur_line (float *ctable, float *cmatrix, int32_t cmatrix_length, uint8_t* cur_col, uint8_t* dest_col, int32_t y, int32_t bytes)
+{
+ float scale;
+ float sum;
+ int32_t i=0, j=0;
+ int32_t row;
+ int32_t cmatrix_middle = cmatrix_length/2;
+
+ float *cmatrix_p;
+ uint8_t *cur_col_p;
+ uint8_t *cur_col_p1;
+ uint8_t *dest_col_p;
+ float *ctable_p;
+
+ /* this first block is the same as the non-optimized version --
+ * it is only used for very small pictures, so speed isn't a
+ * big concern.
+ */
+ if (cmatrix_length > y)
+ {
+ for (row = 0; row < y ; row++)
+ {
+ scale=0;
+ /* find the scale factor */
+ for (j = 0; j < y ; j++)
+ {
+ /* if the index is in bounds, add it to the scale counter */
+ if ((j + cmatrix_middle - row >= 0) &&
+ (j + cmatrix_middle - row < cmatrix_length))
+ scale += cmatrix[j + cmatrix_middle - row];
+ }
+ for (i = 0; i<bytes; i++)
+ {
+ sum = 0;
+ for (j = 0; j < y; j++)
+ {
+ if ((j >= row - cmatrix_middle) &&
+ (j <= row + cmatrix_middle))
+ sum += cur_col[j*bytes + i] * cmatrix[j];
+ }
+ dest_col[row*bytes + i] = (uint8_t)(0.5f + sum / scale);
+ }
+ }
+ }
+ else
+ {
+ /* for the edge condition, we only use available info and scale to one */
+ for (row = 0; row < cmatrix_middle; row++)
+ {
+ /* find scale factor */
+ scale=0;
+ for (j = cmatrix_middle - row; j<cmatrix_length; j++)
+ scale += cmatrix[j];
+ for (i = 0; i<bytes; i++)
+ {
+ sum = 0;
+ for (j = cmatrix_middle - row; j<cmatrix_length; j++)
+ {
+ sum += cur_col[(row + j-cmatrix_middle)*bytes + i] * cmatrix[j];
+ }
+ dest_col[row*bytes + i] = (uint8_t)(0.5f + sum / scale);
+ }
+ }
+ /* go through each pixel in each col */
+ dest_col_p = dest_col + row*bytes;
+ for (; row < y-cmatrix_middle; row++)
+ {
+ cur_col_p = (row - cmatrix_middle) * bytes + cur_col;
+ for (i = 0; i<bytes; i++)
+ {
+ sum = 0;
+ cmatrix_p = cmatrix;
+ cur_col_p1 = cur_col_p;
+ ctable_p = ctable;
+ for (j = cmatrix_length; j>0; j--)
+ {
+ sum += *(ctable_p + *cur_col_p1);
+ cur_col_p1 += bytes;
+ ctable_p += 256;
+ }
+ cur_col_p++;
+ *(dest_col_p++) = (uint8_t)(0.5f + sum);
+ }
+ }
+
+ /* for the edge condition , we only use available info, and scale to one */
+ for (; row < y; row++)
+ {
+ /* find scale factor */
+ scale=0;
+ for (j = 0; j< y-row + cmatrix_middle; j++)
+ scale += cmatrix[j];
+ for (i = 0; i<bytes; i++)
+ {
+ sum = 0;
+ for (j = 0; j<y-row + cmatrix_middle; j++)
+ {
+ sum += cur_col[(row + j-cmatrix_middle)*bytes + i] * cmatrix[j];
+ }
+ dest_col[row*bytes + i] = (uint8_t) (0.5f + sum / scale);
+ }
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \author [DP]
+ */
+void CxImage::blur_text (uint8_t threshold, uint8_t decay, uint8_t max_depth, CxImage* iSrc, CxImage* iDst, uint8_t bytes)
+{
+ int32_t x,y,z,m;
+ uint8_t *pSrc, *pSrc2, *pSrc3, *pDst;
+ uint8_t step,n;
+ int32_t pivot;
+
+ if (max_depth<1) max_depth = 1;
+
+ int32_t nmin,nmax,xmin,xmax,ymin,ymax;
+ xmin = ymin = 0;
+ xmax = iSrc->head.biWidth;
+ ymax = iSrc->head.biHeight;
+
+ if (xmin==xmax || ymin==ymax) return;
+
+ nmin = xmin * bytes;
+ nmax = xmax * bytes;
+
+ CImageIterator itSrc(iSrc);
+ CImageIterator itTmp(iDst);
+
+ double dbScaler = 100.0f/(ymax-ymin)/bytes;
+
+ for (n=0; n<bytes; n++){
+ for (y=ymin+1;y<(ymax-1);y++)
+ {
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)((y-ymin)*dbScaler*(1+n));
+
+ pSrc = itSrc.GetRow(y);
+ pSrc2 = itSrc.GetRow(y+1);
+ pSrc3 = itSrc.GetRow(y-1);
+ pDst = itTmp.GetRow(y);
+
+ //scan left to right
+ for (x=n+nmin /*,i=xmin*/; x<(nmax-1); x+=bytes /*,i++*/)
+ {
+ z=x+bytes;
+ pivot = pSrc[z]-threshold;
+ //find upper corner
+ if (pSrc[x]<pivot && pSrc2[z]<pivot && pSrc3[x]>=pivot){
+ while (z<nmax && pSrc2[z]<pSrc[x+bytes] && pSrc[x+bytes]<=pSrc[z]){
+ z+=bytes;
+ }
+ m = z-x;
+ m = (decay>1) ? ((m/bytes)/decay+1) : m/bytes;
+ if (m>max_depth) m = max_depth;
+ step = (uint8_t)((pSrc[x+bytes]-pSrc[x])/(m+1));
+ while (m-->1){
+ pDst[x+m*bytes] = (uint8_t)(pDst[x]+(step*(m+1)));
+ }
+ }
+ //find lower corner
+ z=x+bytes;
+ if (pSrc[x]<pivot && pSrc3[z]<pivot && pSrc2[x]>=pivot){
+ while (z<nmax && pSrc3[z]<pSrc[x+bytes] && pSrc[x+bytes]<=pSrc[z]){
+ z+=bytes;
+ }
+ m = z-x;
+ m = (decay>1) ? ((m/bytes)/decay+1) : m/bytes;
+ if (m>max_depth) m = max_depth;
+ step = (uint8_t)((pSrc[x+bytes]-pSrc[x])/(m+1));
+ while (m-->1){
+ pDst[x+m*bytes] = (uint8_t)(pDst[x]+(step*(m+1)));
+ }
+ }
+ }
+ //scan right to left
+ for (x=nmax-1-n /*,i=(xmax-1)*/; x>0; x-=bytes /*,i--*/)
+ {
+ z=x-bytes;
+ pivot = pSrc[z]-threshold;
+ //find upper corner
+ if (pSrc[x]<pivot && pSrc2[z]<pivot && pSrc3[x]>=pivot){
+ while (z>n && pSrc2[z]<pSrc[x-bytes] && pSrc[x-bytes]<=pSrc[z]){
+ z-=bytes;
+ }
+ m = x-z;
+ m = (decay>1) ? ((m/bytes)/decay+1) : m/bytes;
+ if (m>max_depth) m = max_depth;
+ step = (uint8_t)((pSrc[x-bytes]-pSrc[x])/(m+1));
+ while (m-->1){
+ pDst[x-m*bytes] = (uint8_t)(pDst[x]+(step*(m+1)));
+ }
+ }
+ //find lower corner
+ z=x-bytes;
+ if (pSrc[x]<pivot && pSrc3[z]<pivot && pSrc2[x]>=pivot){
+ while (z>n && pSrc3[z]<pSrc[x-bytes] && pSrc[x-bytes]<=pSrc[z]){
+ z-=bytes;
+ }
+ m = x-z;
+ m = (decay>1) ? ((m/bytes)/decay+1) : m/bytes;
+ if (m>max_depth) m = max_depth;
+ step = (uint8_t)((pSrc[x-bytes]-pSrc[x])/(m+1));
+ while (m-->1){
+ pDst[x-m*bytes] = (uint8_t)(pDst[x]+(step*(m+1)));
+ }
+ }
+ }
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \author [DP]
+ */
+bool CxImage::TextBlur(uint8_t threshold, uint8_t decay, uint8_t max_depth, bool bBlurHorizontal, bool bBlurVertical, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ RGBQUAD* pPalette=NULL;
+ uint16_t bpp = GetBpp();
+
+ //the routine is optimized for RGB or GrayScale images
+ if (!(head.biBitCount == 24 || IsGrayScale())){
+ pPalette = new RGBQUAD[head.biClrUsed];
+ memcpy(pPalette, GetPalette(),GetPaletteSize());
+ if (!IncreaseBpp(24))
+ return false;
+ }
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ if (bBlurHorizontal)
+ blur_text(threshold, decay, max_depth, this, &tmp, head.biBitCount>>3);
+
+ if (bBlurVertical){
+ CxImage src2(*this);
+ src2.RotateLeft();
+ tmp.RotateLeft();
+ blur_text(threshold, decay, max_depth, &src2, &tmp, head.biBitCount>>3);
+ tmp.RotateRight();
+ }
+
+#if CXIMAGE_SUPPORT_SELECTION
+ //restore the non selected region
+ if (pSelection){
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ if (!BlindSelectionIsInside(x,y)){
+ tmp.BlindSetPixelColor(x,y,BlindGetPixelColor(x,y));
+ }
+ }
+ }
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ //if necessary, restore the original BPP and palette
+ if (pPalette){
+ tmp.DecreaseBpp(bpp, true, pPalette);
+ delete [] pPalette;
+ }
+
+ if (iDst) iDst->Transfer(tmp);
+ else Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \author [nipper]; changes [DP]
+ */
+bool CxImage::GaussianBlur(float radius /*= 1.0f*/, CxImage* iDst /*= 0*/)
+{
+ if (!pDib) return false;
+
+ RGBQUAD* pPalette=NULL;
+ uint16_t bpp = GetBpp();
+
+ //the routine is optimized for RGB or GrayScale images
+ if (!(head.biBitCount == 24 || IsGrayScale())){
+ pPalette = new RGBQUAD[head.biClrUsed];
+ memcpy(pPalette, GetPalette(),GetPaletteSize());
+ if (!IncreaseBpp(24))
+ return false;
+ }
+
+ CxImage tmp_x(*this, false, true, true);
+ if (!tmp_x.IsValid()){
+ strcpy(info.szLastError,tmp_x.GetLastError());
+ return false;
+ }
+
+ // generate convolution matrix and make sure it's smaller than each dimension
+ float *cmatrix = NULL;
+ int32_t cmatrix_length = gen_convolve_matrix(radius, &cmatrix);
+ // generate lookup table
+ float *ctable = gen_lookup_table(cmatrix, cmatrix_length);
+
+ int32_t x,y;
+ int32_t bypp = head.biBitCount>>3;
+
+ CImageIterator itSrc(this);
+ CImageIterator itTmp(&tmp_x);
+
+ double dbScaler = 50.0f/head.biHeight;
+
+ // blur the rows
+ for (y=0;y<head.biHeight;y++)
+ {
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)(y*dbScaler);
+
+ blur_line(ctable, cmatrix, cmatrix_length, itSrc.GetRow(y), itTmp.GetRow(y), head.biWidth, bypp);
+ }
+
+ CxImage tmp_y(tmp_x, false, true, true);
+ if (!tmp_y.IsValid()){
+ strcpy(info.szLastError,tmp_y.GetLastError());
+ return false;
+ }
+
+ CImageIterator itDst(&tmp_y);
+
+ // blur the cols
+ uint8_t* cur_col = (uint8_t*)malloc(bypp*head.biHeight);
+ uint8_t* dest_col = (uint8_t*)malloc(bypp*head.biHeight);
+
+ dbScaler = 50.0f/head.biWidth;
+
+ for (x=0;x<head.biWidth;x++)
+ {
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)(50.0f+x*dbScaler);
+
+ itTmp.GetCol(cur_col, x);
+ itDst.GetCol(dest_col, x);
+ blur_line(ctable, cmatrix, cmatrix_length, cur_col, dest_col, head.biHeight, bypp);
+ itDst.SetCol(dest_col, x);
+ }
+
+ free(cur_col);
+ free(dest_col);
+
+ delete [] cmatrix;
+ delete [] ctable;
+
+#if CXIMAGE_SUPPORT_SELECTION
+ //restore the non selected region
+ if (pSelection){
+ for(y=0; y<head.biHeight; y++){
+ for(x=0; x<head.biWidth; x++){
+ if (!BlindSelectionIsInside(x,y)){
+ tmp_y.BlindSetPixelColor(x,y,BlindGetPixelColor(x,y));
+ }
+ }
+ }
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ //if necessary, restore the original BPP and palette
+ if (pPalette){
+ tmp_y.DecreaseBpp(bpp, false, pPalette);
+ if (iDst) DecreaseBpp(bpp, false, pPalette);
+ delete [] pPalette;
+ }
+
+ if (iDst) iDst->Transfer(tmp_y);
+ else Transfer(tmp_y);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \author [DP],[nipper]
+ */
+bool CxImage::SelectiveBlur(float radius, uint8_t threshold, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ RGBQUAD* pPalette=NULL;
+ uint16_t bpp = GetBpp();
+
+ CxImage Tmp(*this, true, true, true);
+ if (!Tmp.IsValid()){
+ strcpy(info.szLastError,Tmp.GetLastError());
+ return false;
+ }
+
+ //the routine is optimized for RGB or GrayScale images
+ if (!(head.biBitCount == 24 || IsGrayScale())){
+ pPalette = new RGBQUAD[head.biClrUsed];
+ memcpy(pPalette, GetPalette(),GetPaletteSize());
+ if (!Tmp.IncreaseBpp(24)){
+ delete [] pPalette;
+ return false;
+ }
+ }
+
+ CxImage Dst(Tmp, true, true, true);
+ if (!Dst.IsValid()){
+ strcpy(info.szLastError,Dst.GetLastError());
+ delete [] pPalette;
+ return false;
+ }
+
+ //build the difference mask
+ uint8_t thresh_dw = (uint8_t)max( 0 ,(int32_t)(128 - threshold));
+ uint8_t thresh_up = (uint8_t)min(255,(int32_t)(128 + threshold));
+ int32_t kernel[]={-100,-100,-100,-100,801,-100,-100,-100,-100};
+ if (!Tmp.Filter(kernel,3,800,128)){
+ strcpy(info.szLastError,Tmp.GetLastError());
+ delete [] pPalette;
+ return false;
+ }
+
+ //if the image has no selection, build a selection for the whole image
+#if CXIMAGE_SUPPORT_SELECTION
+ if (!Tmp.SelectionIsValid()){
+ Tmp.SelectionCreate();
+ Tmp.SelectionClear(255);
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ xmin = Tmp.info.rSelectionBox.left;
+ xmax = Tmp.info.rSelectionBox.right;
+ ymin = Tmp.info.rSelectionBox.bottom;
+ ymax = Tmp.info.rSelectionBox.top;
+
+ //modify the selection where the difference mask is over the threshold
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+ if(Tmp.BlindSelectionIsInside(x,y)){
+ RGBQUAD c = Tmp.BlindGetPixelColor(x,y);
+ if ((c.rgbRed < thresh_dw || c.rgbRed > thresh_up) ||
+ (c.rgbGreen < thresh_dw || c.rgbGreen > thresh_up) ||
+ (c.rgbBlue < thresh_dw || c.rgbBlue > thresh_up))
+ {
+ Tmp.SelectionSet(x,y,0);
+ }
+ }
+ }
+ }
+
+ //blur the image (only in the selected pixels)
+ Dst.SelectionCopy(Tmp);
+ if (!Dst.GaussianBlur(radius)){
+ strcpy(info.szLastError,Dst.GetLastError());
+ delete [] pPalette;
+ return false;
+ }
+
+ //restore the original selection
+ Dst.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ //if necessary, restore the original BPP and palette
+ if (pPalette){
+ Dst.DecreaseBpp(bpp, false, pPalette);
+ delete [] pPalette;
+ }
+
+ if (iDst) iDst->Transfer(Dst);
+ else Transfer(Dst);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * sharpen the image by subtracting a blurred copy from the original image.
+ * \param radius: width in pixels of the blurring effect. Range: >0; default = 5.
+ * \param amount: strength of the filter. Range: 0.0 (none) to 1.0 (max); default = 0.5
+ * \param threshold: difference, between blurred and original pixel, to trigger the filter
+ * Range: 0 (always triggered) to 255 (never triggered); default = 0.
+ * \return true if everything is ok
+ * \author [nipper]; changes [DP]
+ */
+bool CxImage::UnsharpMask(float radius /*= 5.0*/, float amount /*= 0.5*/, int32_t threshold /*= 0*/)
+{
+ if (!pDib) return false;
+
+ RGBQUAD* pPalette=NULL;
+ uint16_t bpp = GetBpp();
+
+ //the routine is optimized for RGB or GrayScale images
+ if (!(head.biBitCount == 24 || IsGrayScale())){
+ pPalette = new RGBQUAD[head.biClrUsed];
+ memcpy(pPalette, GetPalette(),GetPaletteSize());
+ if (!IncreaseBpp(24))
+ return false;
+ }
+
+ CxImage iDst;
+ if (!GaussianBlur(radius,&iDst))
+ return false;
+
+ CImageIterator itSrc(this);
+ CImageIterator itDst(&iDst);
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ if (xmin==xmax || ymin==ymax)
+ return false;
+
+ double dbScaler = 100.0/(ymax-ymin);
+ int32_t bypp = head.biBitCount>>3;
+
+ // merge the source and destination (which currently contains
+ // the blurred version) images
+ for (int32_t y=ymin; y<ymax; y++)
+ {
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)((y-ymin)*dbScaler);
+
+ // get source row
+ uint8_t* cur_row = itSrc.GetRow(y);
+ // get dest row
+ uint8_t* dest_row = itDst.GetRow(y);
+ // combine the two
+ for (int32_t x=xmin; x<xmax; x++) {
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ for (int32_t b=0, z=x*bypp; b<bypp; b++, z++){
+ int32_t diff = cur_row[z] - dest_row[z];
+
+ // do tresholding
+ if (abs(diff) < threshold){
+ dest_row[z] = cur_row[z];
+ } else {
+ dest_row[z] = (uint8_t)min(255, max(0,(int32_t)(cur_row[z] + amount * diff)));
+ }
+ }
+ }
+ }
+ }
+
+ //if necessary, restore the original BPP and palette
+ if (pPalette){
+ iDst.DecreaseBpp(bpp, false, pPalette);
+ delete [] pPalette;
+ }
+
+ Transfer(iDst);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Apply a look up table to the image.
+ * \param pLut: uint8_t[256] look up table
+ * \return true if everything is ok
+ */
+bool CxImage::Lut(uint8_t* pLut)
+{
+ if (!pDib || !pLut) return false;
+ RGBQUAD color;
+
+ double dbScaler;
+ if (head.biClrUsed==0){
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ // faster loop for full image
+ uint8_t *iSrc=info.pImage;
+ for(uint32_t i=0; i < head.biSizeImage ; i++){
+ *iSrc++ = pLut[*iSrc];
+ }
+ return true;
+ }
+
+ if (xmin==xmax || ymin==ymax)
+ return false;
+
+ dbScaler = 100.0/(ymax-ymin);
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)((y-ymin)*dbScaler); //<Anatoly Ivasyuk>
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ color = BlindGetPixelColor(x,y);
+ color.rgbRed = pLut[color.rgbRed];
+ color.rgbGreen = pLut[color.rgbGreen];
+ color.rgbBlue = pLut[color.rgbBlue];
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+#if CXIMAGE_SUPPORT_SELECTION
+ } else if (pSelection && (head.biBitCount==8) && IsGrayScale()){
+ int32_t xmin,xmax,ymin,ymax;
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+
+ if (xmin==xmax || ymin==ymax)
+ return false;
+
+ dbScaler = 100.0/(ymax-ymin);
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)((y-ymin)*dbScaler);
+ for(int32_t x=xmin; x<xmax; x++){
+ if (BlindSelectionIsInside(x,y))
+ {
+ BlindSetPixelIndex(x,y,pLut[BlindGetPixelIndex(x,y)]);
+ }
+ }
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+ } else {
+ bool bIsGrayScale = IsGrayScale();
+ for(uint32_t j=0; j<head.biClrUsed; j++){
+ color = GetPaletteColor((uint8_t)j);
+ color.rgbRed = pLut[color.rgbRed];
+ color.rgbGreen = pLut[color.rgbGreen];
+ color.rgbBlue = pLut[color.rgbBlue];
+ SetPaletteColor((uint8_t)j,color);
+ }
+ if (bIsGrayScale) GrayScale();
+ }
+ return true;
+
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Apply an indipendent look up table for each channel
+ * \param pLutR, pLutG, pLutB, pLutA: uint8_t[256] look up tables
+ * \return true if everything is ok
+ */
+bool CxImage::Lut(uint8_t* pLutR, uint8_t* pLutG, uint8_t* pLutB, uint8_t* pLutA)
+{
+ if (!pDib || !pLutR || !pLutG || !pLutB) return false;
+ RGBQUAD color;
+
+ double dbScaler;
+ if (head.biClrUsed==0){
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ if (xmin==xmax || ymin==ymax)
+ return false;
+
+ dbScaler = 100.0/(ymax-ymin);
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)((y-ymin)*dbScaler);
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ color = BlindGetPixelColor(x,y);
+ color.rgbRed = pLutR[color.rgbRed];
+ color.rgbGreen = pLutG[color.rgbGreen];
+ color.rgbBlue = pLutB[color.rgbBlue];
+ if (pLutA) color.rgbReserved=pLutA[color.rgbReserved];
+ BlindSetPixelColor(x,y,color,true);
+ }
+ }
+ }
+ } else {
+ bool bIsGrayScale = IsGrayScale();
+ for(uint32_t j=0; j<head.biClrUsed; j++){
+ color = GetPaletteColor((uint8_t)j);
+ color.rgbRed = pLutR[color.rgbRed];
+ color.rgbGreen = pLutG[color.rgbGreen];
+ color.rgbBlue = pLutB[color.rgbBlue];
+ SetPaletteColor((uint8_t)j,color);
+ }
+ if (bIsGrayScale) GrayScale();
+ }
+
+ return true;
+
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Use the RedEyeRemove function to remove the red-eye effect that frequently
+ * occurs in photographs of humans and animals. You must select the region
+ * where the function will filter the red channel.
+ * \param strength: range from 0.0f (no effect) to 1.0f (full effect). Default = 0.8
+ * \return true if everything is ok
+ */
+bool CxImage::RedEyeRemove(float strength)
+{
+ if (!pDib) return false;
+ RGBQUAD color;
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ if (xmin==xmax || ymin==ymax)
+ return false;
+
+ if (strength<0.0f) strength = 0.0f;
+ if (strength>1.0f) strength = 1.0f;
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ float a = 1.0f-5.0f*((float)((x-0.5f*(xmax+xmin))*(x-0.5f*(xmax+xmin))+(y-0.5f*(ymax+ymin))*(y-0.5f*(ymax+ymin))))/((float)((xmax-xmin)*(ymax-ymin)));
+ if (a<0) a=0;
+ color = BlindGetPixelColor(x,y);
+ color.rgbRed = (uint8_t)(a*min(color.rgbGreen,color.rgbBlue)+(1.0f-a)*color.rgbRed);
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Changes the saturation of the image.
+ * \param saturation: can be from -100 to 100, positive values increase the saturation.
+ * \param colorspace: can be 1 (HSL) or 2 (YUV).
+ * \return true if everything is ok
+ */
+bool CxImage::Saturate(const int32_t saturation, const int32_t colorspace)
+{
+ if (!pDib)
+ return false;
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ if (xmin==xmax || ymin==ymax)
+ return false;
+
+ uint8_t cTable[256];
+
+ switch(colorspace)
+ {
+ case 1:
+ {
+ for (int32_t i=0;i<256;i++) {
+ cTable[i] = (uint8_t)max(0,min(255,(int32_t)(i + saturation)));
+ }
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ RGBQUAD c = RGBtoHSL(BlindGetPixelColor(x,y));
+ c.rgbGreen = cTable[c.rgbGreen];
+ c = HSLtoRGB(c);
+ BlindSetPixelColor(x,y,c);
+ }
+ }
+ }
+ }
+ break;
+ case 2:
+ {
+ for (int32_t i=0;i<256;i++) {
+ cTable[i] = (uint8_t)max(0,min(255,(int32_t)((i-128)*(100 + saturation)/100.0f + 128.5f)));
+ }
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ RGBQUAD c = RGBtoYUV(BlindGetPixelColor(x,y));
+ c.rgbGreen = cTable[c.rgbGreen];
+ c.rgbBlue = cTable[c.rgbBlue];
+ c = YUVtoRGB(c);
+ BlindSetPixelColor(x,y,c);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ strcpy(info.szLastError,"Saturate: wrong colorspace");
+ return false;
+ }
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Solarize: convert all colors above a given lightness level into their negative
+ * \param level : lightness threshold. Range = 0 to 255; default = 128.
+ * \param bLinkedChannels: true = compare with luminance, preserve colors (default)
+ * false = compare with independent R,G,B levels
+ * \return true if everything is ok
+ * \author [Priyank Bolia] (priyank_bolia(at)yahoo(dot)com); changes [DP]
+ */
+bool CxImage::Solarize(uint8_t level, bool bLinkedChannels)
+{
+ if (!pDib) return false;
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ if (head.biBitCount<=8){
+ if (IsGrayScale()){ //GRAYSCALE, selection
+ for(int32_t y=ymin; y<ymax; y++){
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ uint8_t index = BlindGetPixelIndex(x,y);
+ RGBQUAD color = GetPaletteColor(index);
+ if ((uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)>level){
+ BlindSetPixelIndex(x,y,255-index);
+ }
+ }
+ }
+ }
+ } else { //PALETTE, full image
+ RGBQUAD* ppal=GetPalette();
+ for(uint32_t i=0;i<head.biClrUsed;i++){
+ RGBQUAD color = GetPaletteColor((uint8_t)i);
+ if (bLinkedChannels){
+ if ((uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)>level){
+ ppal[i].rgbBlue =(uint8_t)(255-ppal[i].rgbBlue);
+ ppal[i].rgbGreen =(uint8_t)(255-ppal[i].rgbGreen);
+ ppal[i].rgbRed =(uint8_t)(255-ppal[i].rgbRed);
+ }
+ } else {
+ if (color.rgbBlue>level) ppal[i].rgbBlue =(uint8_t)(255-ppal[i].rgbBlue);
+ if (color.rgbGreen>level) ppal[i].rgbGreen =(uint8_t)(255-ppal[i].rgbGreen);
+ if (color.rgbRed>level) ppal[i].rgbRed =(uint8_t)(255-ppal[i].rgbRed);
+ }
+ }
+ }
+ } else { //RGB, selection
+ for(int32_t y=ymin; y<ymax; y++){
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ RGBQUAD color = BlindGetPixelColor(x,y);
+ if (bLinkedChannels){
+ if ((uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)>level){
+ color.rgbRed = (uint8_t)(255-color.rgbRed);
+ color.rgbGreen = (uint8_t)(255-color.rgbGreen);
+ color.rgbBlue = (uint8_t)(255-color.rgbBlue);
+ }
+ } else {
+ if (color.rgbBlue>level) color.rgbBlue =(uint8_t)(255-color.rgbBlue);
+ if (color.rgbGreen>level) color.rgbGreen =(uint8_t)(255-color.rgbGreen);
+ if (color.rgbRed>level) color.rgbRed =(uint8_t)(255-color.rgbRed);
+ }
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+ }
+
+ //invert transparent color only in case of full image processing
+ if (pSelection==0 || (!IsGrayScale() && IsIndexed())){
+ if (bLinkedChannels){
+ if ((uint8_t)RGB2GRAY(info.nBkgndColor.rgbRed,info.nBkgndColor.rgbGreen,info.nBkgndColor.rgbBlue)>level){
+ info.nBkgndColor.rgbBlue = (uint8_t)(255-info.nBkgndColor.rgbBlue);
+ info.nBkgndColor.rgbGreen = (uint8_t)(255-info.nBkgndColor.rgbGreen);
+ info.nBkgndColor.rgbRed = (uint8_t)(255-info.nBkgndColor.rgbRed);
+ }
+ } else {
+ if (info.nBkgndColor.rgbBlue>level) info.nBkgndColor.rgbBlue = (uint8_t)(255-info.nBkgndColor.rgbBlue);
+ if (info.nBkgndColor.rgbGreen>level) info.nBkgndColor.rgbGreen = (uint8_t)(255-info.nBkgndColor.rgbGreen);
+ if (info.nBkgndColor.rgbRed>level) info.nBkgndColor.rgbRed = (uint8_t)(255-info.nBkgndColor.rgbRed);
+ }
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Converts the RGB triplets to and from different colorspace
+ * \param dstColorSpace: destination colorspace; 0 = RGB, 1 = HSL, 2 = YUV, 3 = YIQ, 4 = XYZ
+ * \param srcColorSpace: source colorspace; 0 = RGB, 1 = HSL, 2 = YUV, 3 = YIQ, 4 = XYZ
+ * \return true if everything is ok
+ */
+bool CxImage::ConvertColorSpace(const int32_t dstColorSpace, const int32_t srcColorSpace)
+{
+ if (!pDib)
+ return false;
+
+ if (dstColorSpace == srcColorSpace)
+ return true;
+
+ int32_t w = GetWidth();
+ int32_t h = GetHeight();
+
+ for (int32_t y=0;y<h;y++){
+ info.nProgress = (int32_t)(100*y/h);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<w;x++){
+ RGBQUAD c = BlindGetPixelColor(x,y);
+ switch (srcColorSpace){
+ case 0:
+ break;
+ case 1:
+ c = HSLtoRGB(c);
+ break;
+ case 2:
+ c = YUVtoRGB(c);
+ break;
+ case 3:
+ c = YIQtoRGB(c);
+ break;
+ case 4:
+ c = XYZtoRGB(c);
+ break;
+ default:
+ strcpy(info.szLastError,"ConvertColorSpace: unknown source colorspace");
+ return false;
+ }
+ switch (dstColorSpace){
+ case 0:
+ break;
+ case 1:
+ c = RGBtoHSL(c);
+ break;
+ case 2:
+ c = RGBtoYUV(c);
+ break;
+ case 3:
+ c = RGBtoYIQ(c);
+ break;
+ case 4:
+ c = RGBtoXYZ(c);
+ break;
+ default:
+ strcpy(info.szLastError,"ConvertColorSpace: unknown destination colorspace");
+ return false;
+ }
+ BlindSetPixelColor(x,y,c);
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Finds the optimal (global or local) treshold for image binarization
+ * \param method: 0 = average all methods (default); 1 = Otsu; 2 = Kittler & Illingworth; 3 = max entropy; 4 = potential difference;
+ * \param pBox: region from where the threshold is computed; 0 = full image (default).
+ * \param pContrastMask: limit the computation only in regions with contrasted (!=0) pixels; default = 0.
+ * the pContrastMask image must be grayscale with same with and height of the current image,
+ * can be obtained from the current image with a filter:
+ * CxImage iContrastMask(*image,true,false,false);
+ * iContrastMask.GrayScale();
+ * int32_t edge[]={-1,-1,-1,-1,8,-1,-1,-1,-1};
+ * iContrastMask.Filter(edge,3,1,0);
+ * int32_t blur[]={1,1,1,1,1,1,1,1,1};
+ * iContrastMask.Filter(blur,3,9,0);
+ * \return optimal threshold; -1 = error.
+ * \sa AdaptiveThreshold
+ */
+int32_t CxImage::OptimalThreshold(int32_t method, RECT * pBox, CxImage* pContrastMask)
+{
+ if (!pDib)
+ return false;
+
+ if (head.biBitCount!=8){
+ strcpy(info.szLastError,"OptimalThreshold works only on 8 bit images");
+ return -1;
+ }
+
+ if (pContrastMask){
+ if (!pContrastMask->IsValid() ||
+ !pContrastMask->IsGrayScale() ||
+ pContrastMask->GetWidth() != GetWidth() ||
+ pContrastMask->GetHeight() != GetHeight()){
+ strcpy(info.szLastError,"OptimalThreshold invalid ContrastMask");
+ return -1;
+ }
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pBox){
+ xmin = max(pBox->left,0);
+ xmax = min(pBox->right,head.biWidth);
+ ymin = max(pBox->bottom,0);
+ ymax = min(pBox->top,head.biHeight);
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ if (xmin>=xmax || ymin>=ymax)
+ return -1;
+
+ double p[256];
+ memset(p, 0, 256*sizeof(double));
+ //build histogram
+ for (int32_t y = ymin; y<ymax; y++){
+ uint8_t* pGray = GetBits(y) + xmin;
+ uint8_t* pContr = 0;
+ if (pContrastMask) pContr = pContrastMask->GetBits(y) + xmin;
+ for (int32_t x = xmin; x<xmax; x++){
+ uint8_t n = *pGray++;
+ if (pContr){
+ if (*pContr) p[n]++;
+ pContr++;
+ } else {
+ p[n]++;
+ }
+ }
+ }
+
+ //find histogram limits
+ int32_t gray_min = 0;
+ while (gray_min<255 && p[gray_min]==0) gray_min++;
+ int32_t gray_max = 255;
+ while (gray_max>0 && p[gray_max]==0) gray_max--;
+ if (gray_min > gray_max)
+ return -1;
+ if (gray_min == gray_max){
+ if (gray_min == 0)
+ return 0;
+ else
+ return gray_max-1;
+ }
+
+ //compute total moments 0th,1st,2nd order
+ int32_t i,k;
+ double w_tot = 0;
+ double m_tot = 0;
+ double q_tot = 0;
+ for (i = gray_min; i <= gray_max; i++){
+ w_tot += p[i];
+ m_tot += i*p[i];
+ q_tot += i*i*p[i];
+ }
+
+ double L, L1max, L2max, L3max, L4max; //objective functions
+ int32_t th1,th2,th3,th4; //optimal thresholds
+ L1max = L2max = L3max = L4max = 0;
+ th1 = th2 = th3 = th4 = -1;
+
+ double w1, w2, m1, m2, q1, q2, s1, s2;
+ w1 = m1 = q1 = 0;
+ for (i = gray_min; i < gray_max; i++){
+ w1 += p[i];
+ w2 = w_tot - w1;
+ m1 += i*p[i];
+ m2 = m_tot - m1;
+ q1 += i*i*p[i];
+ q2 = q_tot - q1;
+ s1 = q1/w1-m1*m1/w1/w1; //s1 = q1/w1-pow(m1/w1,2);
+ s2 = q2/w2-m2*m2/w2/w2; //s2 = q2/w2-pow(m2/w2,2);
+
+ //Otsu
+ L = -(s1*w1 + s2*w2); //implemented as definition
+ //L = w1 * w2 * (m2/w2 - m1/w1)*(m2/w2 - m1/w1); //implementation that doesn't need s1 & s2
+ if (L1max < L || th1<0){
+ L1max = L;
+ th1 = i;
+ }
+
+ //Kittler and Illingworth
+ if (s1>0 && s2>0){
+ L = w1*log(w1/sqrt(s1))+w2*log(w2/sqrt(s2));
+ //L = w1*log(w1*w1/s1)+w2*log(w2*w2/s2);
+ if (L2max < L || th2<0){
+ L2max = L;
+ th2 = i;
+ }
+ }
+
+ //max entropy
+ L = 0;
+ for (k=gray_min;k<=i;k++) if (p[k] > 0) L -= p[k]*log(p[k]/w1)/w1;
+ for (k;k<=gray_max;k++) if (p[k] > 0) L -= p[k]*log(p[k]/w2)/w2;
+ if (L3max < L || th3<0){
+ L3max = L;
+ th3 = i;
+ }
+
+ //potential difference (based on Electrostatic Binarization method by J. Acharya & G. Sreechakra)
+ // L=-fabs(vdiff/vsum); è molto selettivo, sembra che L=-fabs(vdiff) o L=-(vsum)
+ // abbiano lo stesso valore di soglia... il che semplificherebbe molto la routine
+ double vdiff = 0;
+ for (k=gray_min;k<=i;k++)
+ vdiff += p[k]*(i-k)*(i-k);
+ double vsum = vdiff;
+ for (k;k<=gray_max;k++){
+ double dv = p[k]*(k-i)*(k-i);
+ vdiff -= dv;
+ vsum += dv;
+ }
+ if (vsum>0) L = -fabs(vdiff/vsum); else L = 0;
+ if (L4max < L || th4<0){
+ L4max = L;
+ th4 = i;
+ }
+ }
+
+ int32_t threshold;
+ switch (method){
+ case 1: //Otsu
+ threshold = th1;
+ break;
+ case 2: //Kittler and Illingworth
+ threshold = th2;
+ break;
+ case 3: //max entropy
+ threshold = th3;
+ break;
+ case 4: //potential difference
+ threshold = th4;
+ break;
+ default: //auto
+ {
+ int32_t nt = 0;
+ threshold = 0;
+ if (th1>=0) { threshold += th1; nt++;}
+ if (th2>=0) { threshold += th2; nt++;}
+ if (th3>=0) { threshold += th3; nt++;}
+ if (th4>=0) { threshold += th4; nt++;}
+ if (nt)
+ threshold /= nt;
+ else
+ threshold = (gray_min+gray_max)/2;
+
+ /*better(?) but really expensive alternative:
+ n = 0:255;
+ pth1 = c1(th1)/sqrt(2*pi*s1(th1))*exp(-((n - m1(th1)).^2)/2/s1(th1)) + c2(th1)/sqrt(2*pi*s2(th1))*exp(-((n - m2(th1)).^2)/2/s2(th1));
+ pth2 = c1(th2)/sqrt(2*pi*s1(th2))*exp(-((n - m1(th2)).^2)/2/s1(th2)) + c2(th2)/sqrt(2*pi*s2(th2))*exp(-((n - m2(th2)).^2)/2/s2(th2));
+ ...
+ mse_th1 = sum((p-pth1).^2);
+ mse_th2 = sum((p-pth2).^2);
+ ...
+ select th# that gives minimum mse_th#
+ */
+
+ }
+ }
+
+ if (threshold <= gray_min || threshold >= gray_max)
+ threshold = (gray_min+gray_max)/2;
+
+ return threshold;
+}
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * Converts the image to B&W, using an optimal threshold mask
+ * \param method: 0 = average all methods (default); 1 = Otsu; 2 = Kittler & Illingworth; 3 = max entropy; 4 = potential difference;
+ * \param nBoxSize: the image is divided into "nBoxSize x nBoxSize" blocks, from where the threshold is computed; min = 8; default = 64.
+ * \param pContrastMask: limit the computation only in regions with contrasted (!=0) pixels; default = 0.
+ * \param nBias: global offset added to the threshold mask; default = 0.
+ * \param fGlobalLocalBalance: balance between local and global threshold. default = 0.5
+ * fGlobalLocalBalance can be from 0.0 (use only local threshold) to 1.0 (use only global threshold)
+ * the pContrastMask image must be grayscale with same with and height of the current image,
+ * \return true if everything is ok.
+ * \sa OptimalThreshold
+ */
+bool CxImage::AdaptiveThreshold(int32_t method, int32_t nBoxSize, CxImage* pContrastMask, int32_t nBias, float fGlobalLocalBalance)
+{
+ if (!pDib)
+ return false;
+
+ if (pContrastMask){
+ if (!pContrastMask->IsValid() ||
+ !pContrastMask->IsGrayScale() ||
+ pContrastMask->GetWidth() != GetWidth() ||
+ pContrastMask->GetHeight() != GetHeight()){
+ strcpy(info.szLastError,"AdaptiveThreshold invalid ContrastMask");
+ return false;
+ }
+ }
+
+ if (nBoxSize<8) nBoxSize = 8;
+ if (fGlobalLocalBalance<0.0f) fGlobalLocalBalance = 0.0f;
+ if (fGlobalLocalBalance>1.0f) fGlobalLocalBalance = 1.0f;
+
+ int32_t mw = (head.biWidth + nBoxSize - 1)/nBoxSize;
+ int32_t mh = (head.biHeight + nBoxSize - 1)/nBoxSize;
+
+ CxImage mask(mw,mh,8);
+ if(!mask.GrayScale())
+ return false;
+
+ if(!GrayScale())
+ return false;
+
+ int32_t globalthreshold = OptimalThreshold(method, 0, pContrastMask);
+ if (globalthreshold <0)
+ return false;
+
+ for (int32_t y=0; y<mh; y++){
+ for (int32_t x=0; x<mw; x++){
+ info.nProgress = (int32_t)(100*(x+y*mw)/(mw*mh));
+ if (info.nEscape) break;
+ RECT r;
+ r.left = x*nBoxSize;
+ r.right = r.left + nBoxSize;
+ r.bottom = y*nBoxSize;
+ r.top = r.bottom + nBoxSize;
+ int32_t threshold = OptimalThreshold(method, &r, pContrastMask);
+ if (threshold <0) return false;
+ mask.SetPixelIndex(x,y,(uint8_t)max(0,min(255,nBias+((1.0f-fGlobalLocalBalance)*threshold + fGlobalLocalBalance*globalthreshold))));
+ }
+ }
+
+ mask.Resample(mw*nBoxSize,mh*nBoxSize,0);
+ mask.Crop(0,head.biHeight,head.biWidth,0);
+
+ if(!Threshold(&mask))
+ return false;
+
+ return true;
+}
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * Finds the contour of an object with a given color
+ * \param color_target: object color
+ * \param color_trace: contour color
+ * \return true if everything is ok.
+ * \sa Edge, Contour
+ */
+bool CxImage::Trace(RGBQUAD color_target, RGBQUAD color_trace)
+{
+ if (!pDib) return false;
+
+ RGBQUAD color;
+ bool bFindStartPoint;
+ int32_t nFindPoint;
+ POINT StartPoint,CurrentPoint;
+ int32_t Direction[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}, {0,1},{1,1}};
+ int32_t BeginDirect = 0;
+ int32_t x,y;
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(head.biWidth,head.biHeight,24,info.dwType);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+ tmp.Clear(255);
+
+ CurrentPoint.x = StartPoint.x = CurrentPoint.y = StartPoint.y = 0;
+ bFindStartPoint = false;
+ for (y=head.biHeight-1;y>=0 && !bFindStartPoint;y--){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (x=0;x<head.biWidth && !bFindStartPoint;x++){
+ color = BlindGetPixelColor(x,y);
+ if (color.rgbRed == color_target.rgbRed &&
+ color.rgbGreen == color_target.rgbGreen &&
+ color.rgbBlue == color_target.rgbBlue )
+ {
+ bFindStartPoint = true;
+ CurrentPoint.x = StartPoint.x = x;
+ CurrentPoint.y = StartPoint.y = y;
+ }
+ }
+ }
+
+ while(bFindStartPoint)
+ {
+ nFindPoint = 8;
+ while(nFindPoint)
+ {
+ x = CurrentPoint.x + Direction[BeginDirect][0];
+ y = CurrentPoint.y + Direction[BeginDirect][1];
+ color = GetPixelColor(x,y);
+
+ if (IsInside(x,y) &&
+ color.rgbRed == color_target.rgbRed &&
+ color.rgbGreen == color_target.rgbGreen &&
+ color.rgbBlue == color_target.rgbBlue )
+ {
+ nFindPoint = 0;
+ CurrentPoint.x = x;
+ CurrentPoint.y = y;
+
+ if(x == StartPoint.x && y == StartPoint.y)
+ bFindStartPoint = false;
+
+ tmp.BlindSetPixelColor(x,y,color_trace);
+
+ BeginDirect--;
+ if(BeginDirect == -1) BeginDirect = 7;
+ }
+ else
+ {
+ BeginDirect++;
+ if(BeginDirect == 8) BeginDirect = 0;
+ nFindPoint--;
+ if(nFindPoint == 0) {
+ bFindStartPoint = false;
+ tmp.SetPixelColor(CurrentPoint.x,CurrentPoint.y,color_trace);
+ }
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+
+#ifndef __MINGW32__
+////////////////////////////////////////////////////////////////////////////////
+#include <queue>
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Flood Fill
+ * \param xStart, yStart: starting point
+ * \param cFillColor: filling color
+ * \param nTolerance: deviation from the starting point color
+ * \param nOpacity: can be from 0 (transparent) to 255 (opaque, default)
+ * \param bSelectFilledArea: if true, the pixels in the region are also set in the selection layer; default = false
+ * \param nSelectionLevel: if bSelectFilledArea is true, the selected pixels are set to nSelectionLevel; default = 255
+ * Note: nOpacity=0 && bSelectFilledArea=true act as a "magic wand"
+ * \return true if everything is ok
+ */
+bool CxImage::FloodFill(const int32_t xStart, const int32_t yStart, const RGBQUAD cFillColor, const uint8_t nTolerance,
+ uint8_t nOpacity, const bool bSelectFilledArea, const uint8_t nSelectionLevel)
+{
+ if (!pDib)
+ return false;
+
+ if (!IsInside(xStart,yStart))
+ return true;
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (!SelectionIsInside(xStart,yStart))
+ return true;
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ RGBQUAD* pPalette=NULL;
+ uint16_t bpp = GetBpp();
+ //nTolerance or nOpacity implemented only for grayscale or 24bpp images
+ if ((nTolerance || nOpacity != 255) && !(head.biBitCount == 24 || IsGrayScale())){
+ pPalette = new RGBQUAD[head.biClrUsed];
+ memcpy(pPalette, GetPalette(),GetPaletteSize());
+ if (!IncreaseBpp(24))
+ return false;
+ }
+
+ uint8_t* pFillMask = (uint8_t*)calloc(head.biWidth * head.biHeight,1);
+ if (!pFillMask)
+ return false;
+
+//------------------------------------- Begin of Flood Fill
+ POINT offset[4] = {{-1,0},{0,-1},{1,0},{0,1}};
+ std::queue<POINT> q;
+ POINT point = {xStart,yStart};
+ q.push(point);
+
+ if (IsIndexed()){ //--- Generic indexed image, no tolerance OR Grayscale image with tolerance
+ uint8_t idxRef = GetPixelIndex(xStart,yStart);
+ uint8_t idxFill = GetNearestIndex(cFillColor);
+ uint8_t idxMin = (uint8_t)min(255, max(0,(int32_t)(idxRef - nTolerance)));
+ uint8_t idxMax = (uint8_t)min(255, max(0,(int32_t)(idxRef + nTolerance)));
+
+ while(!q.empty())
+ {
+ point = q.front();
+ q.pop();
+
+ for (int32_t z=0; z<4; z++){
+ int32_t x = point.x + offset[z].x;
+ int32_t y = point.y + offset[z].y;
+ if(IsInside(x,y)){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ uint8_t idx = BlindGetPixelIndex(x, y);
+ uint8_t* pFill = pFillMask + x + y * head.biWidth;
+ if (*pFill==0 && idxMin <= idx && idx <= idxMax )
+ {
+ if (nOpacity>0){
+ if (nOpacity == 255)
+ BlindSetPixelIndex(x, y, idxFill);
+ else
+ BlindSetPixelIndex(x, y, (uint8_t)((idxFill * nOpacity + idx * (255-nOpacity))>>8));
+ }
+ POINT pt = {x,y};
+ q.push(pt);
+ *pFill = 1;
+ }
+ }
+ }
+ }
+ }
+ } else { //--- RGB image
+ RGBQUAD cRef = GetPixelColor(xStart,yStart);
+ RGBQUAD cRefMin, cRefMax;
+ cRefMin.rgbRed = (uint8_t)min(255, max(0,(int32_t)(cRef.rgbRed - nTolerance)));
+ cRefMin.rgbGreen = (uint8_t)min(255, max(0,(int32_t)(cRef.rgbGreen - nTolerance)));
+ cRefMin.rgbBlue = (uint8_t)min(255, max(0,(int32_t)(cRef.rgbBlue - nTolerance)));
+ cRefMax.rgbRed = (uint8_t)min(255, max(0,(int32_t)(cRef.rgbRed + nTolerance)));
+ cRefMax.rgbGreen = (uint8_t)min(255, max(0,(int32_t)(cRef.rgbGreen + nTolerance)));
+ cRefMax.rgbBlue = (uint8_t)min(255, max(0,(int32_t)(cRef.rgbBlue + nTolerance)));
+
+ while(!q.empty())
+ {
+ point = q.front();
+ q.pop();
+
+ for (int32_t z=0; z<4; z++){
+ int32_t x = point.x + offset[z].x;
+ int32_t y = point.y + offset[z].y;
+ if(IsInside(x,y)){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ RGBQUAD cc = BlindGetPixelColor(x, y);
+ uint8_t* pFill = pFillMask + x + y * head.biWidth;
+ if (*pFill==0 &&
+ cRefMin.rgbRed <= cc.rgbRed && cc.rgbRed <= cRefMax.rgbRed &&
+ cRefMin.rgbGreen <= cc.rgbGreen && cc.rgbGreen <= cRefMax.rgbGreen &&
+ cRefMin.rgbBlue <= cc.rgbBlue && cc.rgbBlue <= cRefMax.rgbBlue )
+ {
+ if (nOpacity>0){
+ if (nOpacity == 255)
+ BlindSetPixelColor(x, y, cFillColor);
+ else
+ {
+ cc.rgbRed = (uint8_t)((cFillColor.rgbRed * nOpacity + cc.rgbRed * (255-nOpacity))>>8);
+ cc.rgbGreen = (uint8_t)((cFillColor.rgbGreen * nOpacity + cc.rgbGreen * (255-nOpacity))>>8);
+ cc.rgbBlue = (uint8_t)((cFillColor.rgbBlue * nOpacity + cc.rgbBlue * (255-nOpacity))>>8);
+ BlindSetPixelColor(x, y, cc);
+ }
+ }
+ POINT pt = {x,y};
+ q.push(pt);
+ *pFill = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (pFillMask[xStart+yStart*head.biWidth] == 0 && nOpacity>0){
+ if (nOpacity == 255)
+ BlindSetPixelColor(xStart, yStart, cFillColor);
+ else
+ {
+ RGBQUAD cc = BlindGetPixelColor(xStart, yStart);
+ cc.rgbRed = (uint8_t)((cFillColor.rgbRed * nOpacity + cc.rgbRed * (255-nOpacity))>>8);
+ cc.rgbGreen = (uint8_t)((cFillColor.rgbGreen * nOpacity + cc.rgbGreen * (255-nOpacity))>>8);
+ cc.rgbBlue = (uint8_t)((cFillColor.rgbBlue * nOpacity + cc.rgbBlue * (255-nOpacity))>>8);
+ BlindSetPixelColor(xStart, yStart, cc);
+ }
+ }
+ pFillMask[xStart+yStart*head.biWidth] = 1;
+//------------------------------------- End of Flood Fill
+
+ //if necessary, restore the original BPP and palette
+ if (pPalette){
+ DecreaseBpp(bpp, false, pPalette);
+ delete [] pPalette;
+ }
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (bSelectFilledArea){
+ if (!SelectionIsValid()){
+ if (!SelectionCreate()){
+ return false;
+ }
+ SelectionClear();
+ info.rSelectionBox.right = head.biWidth;
+ info.rSelectionBox.top = head.biHeight;
+ info.rSelectionBox.left = info.rSelectionBox.bottom = 0;
+ }
+ RECT r;
+ SelectionGetBox(r);
+ for (int32_t y = r.bottom; y < r.top; y++){
+ uint8_t* pFill = pFillMask + r.left + y * head.biWidth;
+ for (int32_t x = r.left; x<r.right; x++){
+ if (*pFill) SelectionSet(x,y,nSelectionLevel);
+ pFill++;
+ }
+ }
+ SelectionRebuildBox();
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ free(pFillMask);
+
+ return true;
+}
+#endif //__MINGW32__
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DSP
diff --git a/archive/hge/CxImage/ximaenc.cpp b/archive/hge/CxImage/ximaenc.cpp new file mode 100644 index 0000000..6064e49 --- /dev/null +++ b/archive/hge/CxImage/ximaenc.cpp @@ -0,0 +1,1159 @@ +// xImaCodec.cpp : Encode Decode functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_JPG
+#include "ximajpg.h"
+#endif
+
+#if CXIMAGE_SUPPORT_GIF
+#include "ximagif.h"
+#endif
+
+#if CXIMAGE_SUPPORT_PNG
+#include "ximapng.h"
+#endif
+
+#if CXIMAGE_SUPPORT_MNG
+#include "ximamng.h"
+#endif
+
+#if CXIMAGE_SUPPORT_BMP
+#include "ximabmp.h"
+#endif
+
+#if CXIMAGE_SUPPORT_ICO
+#include "ximaico.h"
+#endif
+
+#if CXIMAGE_SUPPORT_TIF
+#include "ximatif.h"
+#endif
+
+#if CXIMAGE_SUPPORT_TGA
+#include "ximatga.h"
+#endif
+
+#if CXIMAGE_SUPPORT_PCX
+#include "ximapcx.h"
+#endif
+
+#if CXIMAGE_SUPPORT_WBMP
+#include "ximawbmp.h"
+#endif
+
+#if CXIMAGE_SUPPORT_WMF
+#include "ximawmf.h" // <vho> - WMF/EMF support
+#endif
+
+#if CXIMAGE_SUPPORT_JBG
+#include "ximajbg.h"
+#endif
+
+#if CXIMAGE_SUPPORT_JASPER
+#include "ximajas.h"
+#endif
+
+#if CXIMAGE_SUPPORT_SKA
+#include "ximaska.h"
+#endif
+
+#if CXIMAGE_SUPPORT_RAW
+#include "ximaraw.h"
+#endif
+
+#if CXIMAGE_SUPPORT_PSD
+#include "ximapsd.h"
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::EncodeSafeCheck(CxFile *hFile)
+{
+ if (hFile==NULL) {
+ strcpy(info.szLastError,CXIMAGE_ERR_NOFILE);
+ return true;
+ }
+
+ if (pDib==NULL){
+ strcpy(info.szLastError,CXIMAGE_ERR_NOIMAGE);
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+//#ifdef WIN32
+//bool CxImage::Save(LPCWSTR filename, uint32_t imagetype)
+//{
+// FILE* hFile; //file handle to write the image
+// if ((hFile=_wfopen(filename,L"wb"))==NULL) return false;
+// bool bOK = Encode(hFile,imagetype);
+// fclose(hFile);
+// return bOK;
+//}
+//#endif //WIN32
+////////////////////////////////////////////////////////////////////////////////
+// For UNICODE support: char -> TCHAR
+/**
+ * Saves to disk the image in a specific format.
+ * \param filename: file name
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ */
+bool CxImage::Save(const TCHAR * filename, uint32_t imagetype)
+{
+ FILE* hFile; //file handle to write the image
+
+#ifdef WIN32
+ if ((hFile=_tfopen(filename,_T("wb")))==NULL) return false; // For UNICODE support
+#else
+ if ((hFile=fopen(filename,"wb"))==NULL) return false;
+#endif
+
+ bool bOK = Encode(hFile,imagetype);
+ fclose(hFile);
+ return bOK;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Saves to disk the image in a specific format.
+ * \param hFile: file handle, open and enabled for writing.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ */
+bool CxImage::Encode(FILE *hFile, uint32_t imagetype)
+{
+ CxIOFile file(hFile);
+ return Encode(&file,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Saves to memory buffer the image in a specific format.
+ * \param buffer: output memory buffer pointer. Must be NULL,
+ * the function allocates and fill the memory,
+ * the application must free the buffer, see also FreeMemory().
+ * \param size: output memory buffer size.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ */
+bool CxImage::Encode(uint8_t * &buffer, int32_t &size, uint32_t imagetype)
+{
+ if (buffer!=NULL){
+ strcpy(info.szLastError,"the buffer must be empty");
+ return false;
+ }
+ CxMemFile file;
+ file.Open();
+ if(Encode(&file,imagetype)){
+ buffer=file.GetBuffer();
+ size=file.Size();
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Saves to disk the image in a specific format.
+ * \param hFile: file handle (CxMemFile or CxIOFile), with write access.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ * \sa ENUM_CXIMAGE_FORMATS
+ */
+bool CxImage::Encode(CxFile *hFile, uint32_t imagetype)
+{
+
+#if CXIMAGE_SUPPORT_BMP
+ if (CXIMAGE_FORMAT_BMP==imagetype){
+ CxImageBMP *newima = new CxImageBMP;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ if (CXIMAGE_FORMAT_ICO==imagetype){
+ CxImageICO *newima = new CxImageICO;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_TIF
+ if (CXIMAGE_FORMAT_TIF==imagetype){
+ CxImageTIF *newima = new CxImageTIF;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_JPG
+ if (CXIMAGE_FORMAT_JPG==imagetype){
+ CxImageJPG *newima = new CxImageJPG;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ if (CXIMAGE_FORMAT_GIF==imagetype){
+ CxImageGIF *newima = new CxImageGIF;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_PNG
+ if (CXIMAGE_FORMAT_PNG==imagetype){
+ CxImagePNG *newima = new CxImagePNG;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_MNG
+ if (CXIMAGE_FORMAT_MNG==imagetype){
+ CxImageMNG *newima = new CxImageMNG;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_TGA
+ if (CXIMAGE_FORMAT_TGA==imagetype){
+ CxImageTGA *newima = new CxImageTGA;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_PCX
+ if (CXIMAGE_FORMAT_PCX==imagetype){
+ CxImagePCX *newima = new CxImagePCX;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+ if (CXIMAGE_FORMAT_WBMP==imagetype){
+ CxImageWBMP *newima = new CxImageWBMP;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS // <vho> - WMF/EMF support
+ if (CXIMAGE_FORMAT_WMF==imagetype){
+ CxImageWMF *newima = new CxImageWMF;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_JBG
+ if (CXIMAGE_FORMAT_JBG==imagetype){
+ CxImageJBG *newima = new CxImageJBG;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_JASPER
+ if (
+ #if CXIMAGE_SUPPORT_JP2
+ CXIMAGE_FORMAT_JP2==imagetype ||
+ #endif
+ #if CXIMAGE_SUPPORT_JPC
+ CXIMAGE_FORMAT_JPC==imagetype ||
+ #endif
+ #if CXIMAGE_SUPPORT_PGX
+ CXIMAGE_FORMAT_PGX==imagetype ||
+ #endif
+ #if CXIMAGE_SUPPORT_PNM
+ CXIMAGE_FORMAT_PNM==imagetype ||
+ #endif
+ #if CXIMAGE_SUPPORT_RAS
+ CXIMAGE_FORMAT_RAS==imagetype ||
+ #endif
+ false ){
+ CxImageJAS *newima = new CxImageJAS;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile,imagetype)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_SKA
+ if (CXIMAGE_FORMAT_SKA==imagetype){
+ CxImageSKA *newima = new CxImageSKA;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_RAW
+ if (CXIMAGE_FORMAT_RAW==imagetype){
+ CxImageRAW *newima = new CxImageRAW;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_PSD
+ if (CXIMAGE_FORMAT_PSD==imagetype){
+ CxImagePSD *newima = new CxImagePSD;
+ if (!newima) return false;
+ newima->Ghost(this);
+ if (newima->Encode(hFile)){
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ delete newima;
+ return false;
+ }
+ }
+#endif
+
+ strcpy(info.szLastError,"Encode: Unknown format");
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Saves to disk or memory pagecount images, referenced by an array of CxImage pointers.
+ * \param hFile: file handle.
+ * \param pImages: array of CxImage pointers.
+ * \param pagecount: number of images.
+ * \param imagetype: can be CXIMAGE_FORMAT_TIF or CXIMAGE_FORMAT_GIF.
+ * \return true if everything is ok
+ */
+bool CxImage::Encode(FILE * hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype)
+{
+ CxIOFile file(hFile);
+ return Encode(&file, pImages, pagecount,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Saves to disk or memory pagecount images, referenced by an array of CxImage pointers.
+ * \param hFile: file handle (CxMemFile or CxIOFile), with write access.
+ * \param pImages: array of CxImage pointers.
+ * \param pagecount: number of images.
+ * \param imagetype: can be CXIMAGE_FORMAT_TIF, CXIMAGE_FORMAT_GIF or CXIMAGE_FORMAT_ICO.
+ * \return true if everything is ok
+ */
+bool CxImage::Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype)
+{
+#if CXIMAGE_SUPPORT_TIF
+ if (imagetype==CXIMAGE_FORMAT_TIF){
+ CxImageTIF newima;
+ newima.Ghost(this);
+ if (newima.Encode(hFile,pImages,pagecount)){
+ return true;
+ } else {
+ strcpy(info.szLastError,newima.GetLastError());
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ if (imagetype==CXIMAGE_FORMAT_GIF){
+ CxImageGIF newima;
+ newima.Ghost(this);
+ if (newima.Encode(hFile,pImages,pagecount)){
+ return true;
+ } else {
+ strcpy(info.szLastError,newima.GetLastError());
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ if (imagetype==CXIMAGE_FORMAT_ICO){
+ CxImageICO newima;
+ newima.Ghost(this);
+ if (newima.Encode(hFile,pImages,pagecount)){
+ return true;
+ } else {
+ strcpy(info.szLastError,newima.GetLastError());
+ return false;
+ }
+ }
+#endif
+ strcpy(info.szLastError,"Multipage Encode, Unsupported operation for this format");
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * exports the image into a RGBA buffer, Useful for OpenGL applications.
+ * \param buffer: output memory buffer pointer. Must be NULL,
+ * the function allocates and fill the memory,
+ * the application must free the buffer, see also FreeMemory().
+ * \param size: output memory buffer size.
+ * \param bFlipY: direction of Y axis. default = false.
+ * \return true if everything is ok
+ */
+bool CxImage::Encode2RGBA(uint8_t * &buffer, int32_t &size, bool bFlipY)
+{
+ if (buffer!=NULL){
+ strcpy(info.szLastError,"the buffer must be empty");
+ return false;
+ }
+ CxMemFile file;
+ file.Open();
+ if(Encode2RGBA(&file,bFlipY)){
+ buffer=file.GetBuffer();
+ size=file.Size();
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * exports the image into a RGBA buffer, Useful for OpenGL applications.
+ * \param hFile: file handle (CxMemFile or CxIOFile), with write access.
+ * \param bFlipY: direction of Y axis. default = false.
+ * \return true if everything is ok
+ */
+bool CxImage::Encode2RGBA(CxFile *hFile, bool bFlipY)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ for (int32_t y1 = 0; y1 < head.biHeight; y1++) {
+ int32_t y = bFlipY ? head.biHeight - 1 - y1 : y1;
+ for(int32_t x = 0; x < head.biWidth; x++) {
+ RGBQUAD color = BlindGetPixelColor(x,y);
+ hFile->PutC(color.rgbRed);
+ hFile->PutC(color.rgbGreen);
+ hFile->PutC(color.rgbBlue);
+ hFile->PutC(color.rgbReserved);
+ }
+ }
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+// For UNICODE support: char -> TCHAR
+/**
+ * Reads from disk the image in a specific format.
+ * - If decoding fails using the specified image format,
+ * the function will try the automatic file format recognition.
+ *
+ * \param filename: file name
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ */
+bool CxImage::Load(const TCHAR * filename, uint32_t imagetype)
+//bool CxImage::Load(const char * filename, uint32_t imagetype)
+{
+ /*FILE* hFile; //file handle to read the image
+ if ((hFile=fopen(filename,"rb"))==NULL) return false;
+ bool bOK = Decode(hFile,imagetype);
+ fclose(hFile);*/
+
+ /* automatic file type recognition */
+ bool bOK = false;
+ if ( GetTypeIndexFromId(imagetype) ){
+ FILE* hFile; //file handle to read the image
+
+#ifdef WIN32
+ if ((hFile=_tfopen(filename,_T("rb")))==NULL) return false; // For UNICODE support
+#else
+ if ((hFile=fopen(filename,"rb"))==NULL) return false;
+#endif
+
+ bOK = Decode(hFile,imagetype);
+ fclose(hFile);
+ if (bOK) return bOK;
+ }
+
+ char szError[256];
+ strcpy(szError,info.szLastError); //save the first error
+
+ // if failed, try automatic recognition of the file...
+ FILE* hFile;
+
+#ifdef WIN32
+ if ((hFile=_tfopen(filename,_T("rb")))==NULL) return false; // For UNICODE support
+#else
+ if ((hFile=fopen(filename,"rb"))==NULL) return false;
+#endif
+
+ bOK = Decode(hFile,CXIMAGE_FORMAT_UNKNOWN);
+ fclose(hFile);
+
+ if (!bOK && imagetype > 0) strcpy(info.szLastError,szError); //restore the first error
+
+ return bOK;
+}
+////////////////////////////////////////////////////////////////////////////////
+#ifdef WIN32
+//bool CxImage::Load(LPCWSTR filename, uint32_t imagetype)
+//{
+// /*FILE* hFile; //file handle to read the image
+// if ((hFile=_wfopen(filename, L"rb"))==NULL) return false;
+// bool bOK = Decode(hFile,imagetype);
+// fclose(hFile);*/
+//
+// /* automatic file type recognition */
+// bool bOK = false;
+// if ( GetTypeIndexFromId(imagetype) ){
+// FILE* hFile; //file handle to read the image
+// if ((hFile=_wfopen(filename,L"rb"))==NULL) return false;
+// bOK = Decode(hFile,imagetype);
+// fclose(hFile);
+// if (bOK) return bOK;
+// }
+//
+// char szError[256];
+// strcpy(szError,info.szLastError); //save the first error
+//
+// // if failed, try automatic recognition of the file...
+// FILE* hFile; //file handle to read the image
+// if ((hFile=_wfopen(filename,L"rb"))==NULL) return false;
+// bOK = Decode(hFile,CXIMAGE_FORMAT_UNKNOWN);
+// fclose(hFile);
+//
+// if (!bOK && imagetype > 0) strcpy(info.szLastError,szError); //restore the first error
+//
+// return bOK;
+//}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Loads an image from the application resources.
+ * \param hRes: the resource handle returned by FindResource().
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS.
+ * \param hModule: NULL for internal resource, or external application/DLL hinstance returned by LoadLibray.
+ * \return true if everything is ok
+ */
+bool CxImage::LoadResource(HRSRC hRes, uint32_t imagetype, HMODULE hModule)
+{
+ uint32_t rsize=SizeofResource(hModule,hRes);
+ HGLOBAL hMem=::LoadResource(hModule,hRes);
+ if (hMem){
+ char* lpVoid=(char*)LockResource(hMem);
+ if (lpVoid){
+ // FILE* fTmp=tmpfile(); doesn't work with network
+ /*char tmpPath[MAX_PATH] = {0};
+ char tmpFile[MAX_PATH] = {0};
+ GetTempPath(MAX_PATH,tmpPath);
+ GetTempFileName(tmpPath,"IMG",0,tmpFile);
+ FILE* fTmp=fopen(tmpFile,"w+b");
+ if (fTmp){
+ fwrite(lpVoid,rsize,1,fTmp);
+ fseek(fTmp,0,SEEK_SET);
+ bool bOK = Decode(fTmp,imagetype);
+ fclose(fTmp);
+ DeleteFile(tmpFile);
+ return bOK;
+ }*/
+
+ CxMemFile fTmp((uint8_t*)lpVoid,rsize);
+ return Decode(&fTmp,imagetype);
+ }
+ } else strcpy(info.szLastError,"Unable to load resource!");
+ return false;
+}
+#endif //WIN32
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Constructor from file name, see Load()
+ * \param filename: file name
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ */
+//
+// > filename: file name
+// > imagetype: specify the image format (CXIMAGE_FORMAT_BMP,...)
+// For UNICODE support: char -> TCHAR
+CxImage::CxImage(const TCHAR * filename, uint32_t imagetype)
+//CxImage::CxImage(const char * filename, uint32_t imagetype)
+{
+ Startup(imagetype);
+ Load(filename,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Constructor from file handle, see Decode()
+ * \param stream: file handle, with read access.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ */
+CxImage::CxImage(FILE * stream, uint32_t imagetype)
+{
+ Startup(imagetype);
+ Decode(stream,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Constructor from CxFile object, see Decode()
+ * \param stream: file handle (CxMemFile or CxIOFile), with read access.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ */
+CxImage::CxImage(CxFile * stream, uint32_t imagetype)
+{
+ Startup(imagetype);
+ Decode(stream,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Constructor from memory buffer, see Decode()
+ * \param buffer: memory buffer
+ * \param size: size of buffer
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ */
+CxImage::CxImage(uint8_t * buffer, uint32_t size, uint32_t imagetype)
+{
+ Startup(imagetype);
+ CxMemFile stream(buffer,size);
+ Decode(&stream,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Loads an image from memory buffer
+ * \param buffer: memory buffer
+ * \param size: size of buffer
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ */
+bool CxImage::Decode(uint8_t * buffer, uint32_t size, uint32_t imagetype)
+{
+ CxMemFile file(buffer,size);
+ return Decode(&file,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Loads an image from file handle.
+ * \param hFile: file handle, with read access.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ */
+bool CxImage::Decode(FILE *hFile, uint32_t imagetype)
+{
+ CxIOFile file(hFile);
+ return Decode(&file,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Loads an image from CxFile object
+ * \param hFile: file handle (CxMemFile or CxIOFile), with read access.
+ * \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
+ * \return true if everything is ok
+ * \sa ENUM_CXIMAGE_FORMATS
+ */
+bool CxImage::Decode(CxFile *hFile, uint32_t imagetype)
+{
+ if (hFile == NULL){
+ strcpy(info.szLastError,CXIMAGE_ERR_NOFILE);
+ return false;
+ }
+
+ uint32_t pos = hFile->Tell();
+
+#if CXIMAGE_SUPPORT_BMP
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_BMP==imagetype){
+ CxImageBMP *newima = new CxImageBMP;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_JPG
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_JPG==imagetype){
+ CxImageJPG *newima = new CxImageJPG;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_ICO==imagetype){
+ CxImageICO *newima = new CxImageICO;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ info.nNumFrames = newima->info.nNumFrames;
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_GIF==imagetype){
+ CxImageGIF *newima = new CxImageGIF;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ info.nNumFrames = newima->info.nNumFrames;
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_PNG
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PNG==imagetype){
+ CxImagePNG *newima = new CxImagePNG;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_TIF
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_TIF==imagetype){
+ CxImageTIF *newima = new CxImageTIF;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ info.nNumFrames = newima->info.nNumFrames;
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_MNG
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_MNG==imagetype){
+ CxImageMNG *newima = new CxImageMNG;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ info.nNumFrames = newima->info.nNumFrames;
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_TGA
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_TGA==imagetype){
+ CxImageTGA *newima = new CxImageTGA;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_PCX
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PCX==imagetype){
+ CxImagePCX *newima = new CxImagePCX;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_WBMP==imagetype){
+ CxImageWBMP *newima = new CxImageWBMP;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_WMF==imagetype){
+ CxImageWMF *newima = new CxImageWMF;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_JBG
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_JBG==imagetype){
+ CxImageJBG *newima = new CxImageJBG;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_JASPER
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype ||
+#if CXIMAGE_SUPPORT_JP2
+ CXIMAGE_FORMAT_JP2==imagetype ||
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ CXIMAGE_FORMAT_JPC==imagetype ||
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ CXIMAGE_FORMAT_PGX==imagetype ||
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ CXIMAGE_FORMAT_PNM==imagetype ||
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ CXIMAGE_FORMAT_RAS==imagetype ||
+#endif
+ false ){
+ CxImageJAS *newima = new CxImageJAS;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_SKA
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_SKA==imagetype){
+ CxImageSKA *newima = new CxImageSKA;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_RAW
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_RAW==imagetype){
+ CxImageRAW *newima = new CxImageRAW;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+#if CXIMAGE_SUPPORT_PSD
+ if (CXIMAGE_FORMAT_UNKNOWN==imagetype || CXIMAGE_FORMAT_PSD==imagetype){
+ CxImagePSD *newima = new CxImagePSD;
+ if (!newima)
+ return false;
+ newima->CopyInfo(*this);
+ if (newima->Decode(hFile)) {
+ Transfer(*newima);
+ delete newima;
+ return true;
+ } else {
+ strcpy(info.szLastError,newima->GetLastError());
+ hFile->Seek(pos,SEEK_SET);
+ delete newima;
+ if (CXIMAGE_FORMAT_UNKNOWN!=imagetype)
+ return false;
+ }
+ }
+#endif
+
+ strcpy(info.szLastError,"Decode: Unknown or wrong format");
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Loads an image from CxFile object
+ * \param hFile: file handle (CxMemFile or CxIOFile), with read access.
+ * \param imagetype: file format, default = 0 (CXIMAGE_FORMAT_UNKNOWN)
+ * \return : if imagetype is not 0, the function returns true when imagetype
+ * matches the file image format. If imagetype is 0, the function returns true
+ * when the file image format is recognized as a supported format.
+ * If the returned value is true, use GetHeight(), GetWidth() or GetType()
+ * to retrieve the basic image information.
+ * \sa ENUM_CXIMAGE_FORMATS
+ */
+bool CxImage::CheckFormat(CxFile * hFile, uint32_t imagetype)
+{
+ SetType(CXIMAGE_FORMAT_UNKNOWN);
+ SetEscape(-1);
+
+ if (!Decode(hFile,imagetype))
+ return false;
+
+ if (GetType() == CXIMAGE_FORMAT_UNKNOWN ||
+ ((imagetype!=CXIMAGE_FORMAT_UNKNOWN)&&(GetType() != imagetype)))
+ return false;
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::CheckFormat(uint8_t * buffer, uint32_t size, uint32_t imagetype)
+{
+ if (buffer==NULL || size==0){
+ strcpy(info.szLastError,"invalid or empty buffer");
+ return false;
+ }
+ CxMemFile file(buffer,size);
+ return CheckFormat(&file,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_EXIF
+bool CxImage::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
+{
+ switch (type){
+#if CXIMAGE_SUPPORT_RAW
+ case CXIMAGE_FORMAT_RAW:
+ {
+ CxImageRAW image;
+ return image.GetExifThumbnail(filename, outname, type);
+ }
+#endif //CXIMAGE_SUPPORT_RAW
+#if CXIMAGE_SUPPORT_JPG
+ case CXIMAGE_FORMAT_JPG:
+ {
+ CxImageJPG image;
+ return image.GetExifThumbnail(filename, outname, type);
+ }
+#endif //CXIMAGE_SUPPORT_JPG
+ default:
+ return false;
+ }
+}
+#endif //CXIMAGE_SUPPORT_EXIF
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
diff --git a/archive/hge/CxImage/ximaexif.cpp b/archive/hge/CxImage/ximaexif.cpp new file mode 100644 index 0000000..f880d72 --- /dev/null +++ b/archive/hge/CxImage/ximaexif.cpp @@ -0,0 +1,877 @@ +/*
+ * File: ximaexif.cpp
+ * Purpose: EXIF reader
+ * 18/Aug/2002 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ * based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
+ */
+
+#include "ximajpg.h"
+
+#if CXIMAGEJPG_SUPPORT_EXIF
+
+////////////////////////////////////////////////////////////////////////////////
+CxImageJPG::CxExifInfo::CxExifInfo(EXIFINFO* info)
+{
+ if (info) {
+ m_exifinfo = info;
+ freeinfo = false;
+ } else {
+ m_exifinfo = new EXIFINFO;
+ memset(m_exifinfo,0,sizeof(EXIFINFO));
+ freeinfo = true;
+ }
+
+ m_szLastError[0]='\0';
+ ExifImageWidth = MotorolaOrder = 0;
+ SectionsRead=0;
+ memset(&Sections, 0, MAX_SECTIONS * sizeof(Section_t));
+}
+////////////////////////////////////////////////////////////////////////////////
+CxImageJPG::CxExifInfo::~CxExifInfo()
+{
+ for(int32_t i=0;i<MAX_SECTIONS;i++) if(Sections[i].Data) free(Sections[i].Data);
+ if (freeinfo) delete m_exifinfo;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJPG::CxExifInfo::DecodeExif(CxFile * hFile, int32_t nReadMode)
+{
+ int32_t a;
+ int32_t HaveCom = FALSE;
+
+ a = hFile->GetC();
+
+ if (a != 0xff || hFile->GetC() != M_SOI){
+ return FALSE;
+ }
+
+ for(;;){
+ int32_t itemlen;
+ int32_t marker = 0;
+ int32_t ll,lh, got;
+ uint8_t * Data;
+
+ if (SectionsRead >= MAX_SECTIONS){
+ strcpy(m_szLastError,"Too many sections in jpg file");
+ return false;
+ }
+
+ for (a=0;a<7;a++){
+ marker = hFile->GetC();
+ if (marker != 0xff) break;
+
+ if (a >= 6){
+ printf("too many padding bytes\n");
+ return false;
+ }
+ }
+
+ if (marker == 0xff){
+ // 0xff is legal padding, but if we get that many, something's wrong.
+ strcpy(m_szLastError,"too many padding bytes!");
+ return false;
+ }
+
+ Sections[SectionsRead].Type = marker;
+
+ // Read the length of the section.
+ lh = hFile->GetC();
+ ll = hFile->GetC();
+
+ itemlen = (lh << 8) | ll;
+
+ if (itemlen < 2){
+ strcpy(m_szLastError,"invalid marker");
+ return false;
+ }
+
+ Sections[SectionsRead].Size = itemlen;
+
+ Data = (uint8_t *)malloc(itemlen);
+ if (Data == NULL){
+ strcpy(m_szLastError,"Could not allocate memory");
+ return false;
+ }
+ Sections[SectionsRead].Data = Data;
+
+ // Store first two pre-read bytes.
+ Data[0] = (uint8_t)lh;
+ Data[1] = (uint8_t)ll;
+
+ got = hFile->Read(Data+2, 1, itemlen-2); // Read the whole section.
+ if (got != itemlen-2){
+ strcpy(m_szLastError,"Premature end of file?");
+ return false;
+ }
+ SectionsRead += 1;
+
+ switch(marker){
+
+ case M_SOS: // stop before hitting compressed data
+ // If reading entire image is requested, read the rest of the data.
+ if (nReadMode & EXIF_READ_IMAGE){
+ int32_t cp, ep, size;
+ // Determine how much file is left.
+ cp = hFile->Tell();
+ hFile->Seek(0, SEEK_END);
+ ep = hFile->Tell();
+ hFile->Seek(cp, SEEK_SET);
+
+ size = ep-cp;
+ Data = (uint8_t *)malloc(size);
+ if (Data == NULL){
+ strcpy(m_szLastError,"could not allocate data for entire image");
+ return false;
+ }
+
+ got = hFile->Read(Data, 1, size);
+ if (got != size){
+ strcpy(m_szLastError,"could not read the rest of the image");
+ return false;
+ }
+
+ Sections[SectionsRead].Data = Data;
+ Sections[SectionsRead].Size = size;
+ Sections[SectionsRead].Type = PSEUDO_IMAGE_MARKER;
+ SectionsRead ++;
+ }
+ return true;
+
+ case M_EOI: // in case it's a tables-only JPEG stream
+ printf("No image in jpeg!\n");
+ return FALSE;
+
+ case M_COM: // Comment section
+ if (HaveCom || ((nReadMode & EXIF_READ_EXIF) == 0)){
+ // Discard this section.
+ free(Sections[--SectionsRead].Data);
+ Sections[SectionsRead].Data=0;
+ }else{
+ process_COM(Data, itemlen);
+ HaveCom = TRUE;
+ }
+ break;
+
+ case M_JFIF:
+ // Regular jpegs always have this tag, exif images have the exif
+ // marker instead, althogh ACDsee will write images with both markers.
+ // this program will re-create this marker on absence of exif marker.
+ // hence no need to keep the copy from the file.
+ free(Sections[--SectionsRead].Data);
+ Sections[SectionsRead].Data=0;
+ break;
+
+ case M_EXIF:
+ // Seen files from some 'U-lead' software with Vivitar scanner
+ // that uses marker 31 for non exif stuff. Thus make sure
+ // it says 'Exif' in the section before treating it as exif.
+ if ((nReadMode & EXIF_READ_EXIF) && memcmp(Data+2, "Exif", 4) == 0){
+ m_exifinfo->IsExif = process_EXIF((uint8_t *)Data+2, itemlen);
+ }else{
+ // Discard this section.
+ free(Sections[--SectionsRead].Data);
+ Sections[SectionsRead].Data=0;
+ }
+ break;
+
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF2:
+ case M_SOF3:
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ process_SOFn(Data, marker);
+ break;
+ default:
+ // Skip any other sections.
+ //if (ShowTags) printf("Jpeg section marker 0x%02x size %d\n",marker, itemlen);
+ break;
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/*--------------------------------------------------------------------------
+ Process a EXIF marker
+ Describes all the drivel that most digital cameras include...
+--------------------------------------------------------------------------*/
+bool CxImageJPG::CxExifInfo::process_EXIF(uint8_t * CharBuf, uint32_t length)
+{
+ m_exifinfo->FlashUsed = 0;
+ /* If it's from a digicam, and it used flash, it says so. */
+ m_exifinfo->Comments[0] = '\0'; /* Initial value - null string */
+
+ ExifImageWidth = 0;
+
+ { /* Check the EXIF header component */
+ static const uint8_t ExifHeader[] = "Exif\0\0";
+ if (memcmp(CharBuf+0, ExifHeader,6)){
+ strcpy(m_szLastError,"Incorrect Exif header");
+ return false;
+ }
+ }
+
+ if (memcmp(CharBuf+6,"II",2) == 0){
+ MotorolaOrder = 0;
+ }else{
+ if (memcmp(CharBuf+6,"MM",2) == 0){
+ MotorolaOrder = 1;
+ }else{
+ strcpy(m_szLastError,"Invalid Exif alignment marker.");
+ return false;
+ }
+ }
+
+ /* Check the next two values for correctness. */
+ if (Get16u(CharBuf+8) != 0x2a){
+ strcpy(m_szLastError,"Invalid Exif start (1)");
+ return false;
+ }
+
+ int32_t FirstOffset = Get32u(CharBuf+10);
+ /* <Richard Collins>
+ if (FirstOffset < 8 || FirstOffset > 16){
+ // I used to ensure this was set to 8 (website I used indicated its 8)
+ // but PENTAX Optio 230 has it set differently, and uses it as offset. (Sept 11 2002)
+ strcpy(m_szLastError,"Suspicious offset of first IFD value");
+ return false;
+ }*/
+
+ uint8_t * LastExifRefd = CharBuf;
+
+ /* First directory starts 16 bytes in. Offsets start at 8 bytes in. */
+ if (!ProcessExifDir(CharBuf+14, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
+ return false;
+
+ /* <Richard Collins> give a chance for a second directory */
+ if (FirstOffset > 8) {
+ if (!ProcessExifDir(CharBuf+14+FirstOffset-8, CharBuf+6, length-6, m_exifinfo, &LastExifRefd))
+ return false;
+ }
+
+ /* This is how far the interesting (non thumbnail) part of the exif went. */
+ // int32_t ExifSettingsLength = LastExifRefd - CharBuf;
+
+ /* Compute the CCD width, in milimeters. */
+ if (m_exifinfo->FocalplaneXRes != 0){
+ m_exifinfo->CCDWidth = (float)(ExifImageWidth * m_exifinfo->FocalplaneUnits / m_exifinfo->FocalplaneXRes);
+ }
+
+ return true;
+}
+//--------------------------------------------------------------------------
+// Get 16 bits motorola order (always) for jpeg header stuff.
+//--------------------------------------------------------------------------
+int32_t CxImageJPG::CxExifInfo::Get16m(void * Short)
+{
+ return (((uint8_t *)Short)[0] << 8) | ((uint8_t *)Short)[1];
+}
+////////////////////////////////////////////////////////////////////////////////
+/*--------------------------------------------------------------------------
+ Convert a 16 bit unsigned value from file's native byte order
+--------------------------------------------------------------------------*/
+int32_t CxImageJPG::CxExifInfo::Get16u(void * Short)
+{
+ if (MotorolaOrder){
+ return (((uint8_t *)Short)[0] << 8) | ((uint8_t *)Short)[1];
+ }else{
+ return (((uint8_t *)Short)[1] << 8) | ((uint8_t *)Short)[0];
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/*--------------------------------------------------------------------------
+ Convert a 32 bit signed value from file's native byte order
+--------------------------------------------------------------------------*/
+int32_t CxImageJPG::CxExifInfo::Get32s(void * Long)
+{
+ if (MotorolaOrder){
+ return ((( char *)Long)[0] << 24) | (((uint8_t *)Long)[1] << 16)
+ | (((uint8_t *)Long)[2] << 8 ) | (((uint8_t *)Long)[3] << 0 );
+ }else{
+ return ((( char *)Long)[3] << 24) | (((uint8_t *)Long)[2] << 16)
+ | (((uint8_t *)Long)[1] << 8 ) | (((uint8_t *)Long)[0] << 0 );
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/*--------------------------------------------------------------------------
+ Convert a 32 bit unsigned value from file's native byte order
+--------------------------------------------------------------------------*/
+uint32_t CxImageJPG::CxExifInfo::Get32u(void * Long)
+{
+ return (uint32_t)Get32s(Long) & 0xffffffff;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+/* Describes format descriptor */
+static const int32_t BytesPerFormat[] = {0,1,1,2,4,8,1,1,2,4,8,4,8};
+#define NUM_FORMATS 12
+
+#define FMT_BYTE 1
+#define FMT_STRING 2
+#define FMT_USHORT 3
+#define FMT_ULONG 4
+#define FMT_URATIONAL 5
+#define FMT_SBYTE 6
+#define FMT_UNDEFINED 7
+#define FMT_SSHORT 8
+#define FMT_SLONG 9
+#define FMT_SRATIONAL 10
+#define FMT_SINGLE 11
+#define FMT_DOUBLE 12
+
+/* Describes tag values */
+
+#define TAG_EXIF_VERSION 0x9000
+#define TAG_EXIF_OFFSET 0x8769
+#define TAG_INTEROP_OFFSET 0xa005
+
+#define TAG_MAKE 0x010F
+#define TAG_MODEL 0x0110
+
+#define TAG_ORIENTATION 0x0112
+#define TAG_XRESOLUTION 0x011A
+#define TAG_YRESOLUTION 0x011B
+#define TAG_RESOLUTIONUNIT 0x0128
+
+#define TAG_EXPOSURETIME 0x829A
+#define TAG_FNUMBER 0x829D
+
+#define TAG_SHUTTERSPEED 0x9201
+#define TAG_APERTURE 0x9202
+#define TAG_BRIGHTNESS 0x9203
+#define TAG_MAXAPERTURE 0x9205
+#define TAG_FOCALLENGTH 0x920A
+
+#define TAG_DATETIME_ORIGINAL 0x9003
+#define TAG_USERCOMMENT 0x9286
+
+#define TAG_SUBJECT_DISTANCE 0x9206
+#define TAG_FLASH 0x9209
+
+#define TAG_FOCALPLANEXRES 0xa20E
+#define TAG_FOCALPLANEYRES 0xa20F
+#define TAG_FOCALPLANEUNITS 0xa210
+#define TAG_EXIF_IMAGEWIDTH 0xA002
+#define TAG_EXIF_IMAGELENGTH 0xA003
+
+/* the following is added 05-jan-2001 vcs */
+#define TAG_EXPOSURE_BIAS 0x9204
+#define TAG_WHITEBALANCE 0x9208
+#define TAG_METERING_MODE 0x9207
+#define TAG_EXPOSURE_PROGRAM 0x8822
+#define TAG_ISO_EQUIVALENT 0x8827
+#define TAG_COMPRESSION_LEVEL 0x9102
+
+#define TAG_THUMBNAIL_OFFSET 0x0201
+#define TAG_THUMBNAIL_LENGTH 0x0202
+
+
+/*--------------------------------------------------------------------------
+ Process one of the nested EXIF directories.
+--------------------------------------------------------------------------*/
+bool CxImageJPG::CxExifInfo::ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength,
+ EXIFINFO * const m_exifinfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel)
+{
+ int32_t de;
+ int32_t a;
+ int32_t NumDirEntries;
+ unsigned ThumbnailOffset = 0;
+ unsigned ThumbnailSize = 0;
+
+ if (NestingLevel > 4){
+ strcpy(m_szLastError,"Maximum directory nesting exceeded (corrupt exif header)");
+ return false;
+ }
+
+ NumDirEntries = Get16u(DirStart);
+
+ if ((DirStart+2+NumDirEntries*12) > (OffsetBase+ExifLength)){
+ strcpy(m_szLastError,"Illegally sized directory");
+ return false;
+ }
+
+ for (de=0;de<NumDirEntries;de++){
+ int32_t Tag, Format, Components;
+ uint8_t * ValuePtr;
+ /* This actually can point to a variety of things; it must be
+ cast to other types when used. But we use it as a byte-by-byte
+ cursor, so we declare it as a pointer to a generic byte here.
+ */
+ int32_t ByteCount;
+ uint8_t * DirEntry;
+ DirEntry = DirStart+2+12*de;
+
+ Tag = Get16u(DirEntry);
+ Format = Get16u(DirEntry+2);
+ Components = Get32u(DirEntry+4);
+
+ if ((Format-1) >= NUM_FORMATS) {
+ /* (-1) catches illegal zero case as unsigned underflows to positive large */
+ strcpy(m_szLastError,"Illegal format code in EXIF dir");
+ return false;
+ }
+
+ ByteCount = Components * BytesPerFormat[Format];
+
+ if (ByteCount > 4){
+ unsigned OffsetVal;
+ OffsetVal = Get32u(DirEntry+8);
+ /* If its bigger than 4 bytes, the dir entry contains an offset.*/
+ if (OffsetVal+ByteCount > ExifLength){
+ /* Bogus pointer offset and / or bytecount value */
+ strcpy(m_szLastError,"Illegal pointer offset value in EXIF.");
+ return false;
+ }
+ ValuePtr = OffsetBase+OffsetVal;
+ }else{
+ /* 4 bytes or less and value is in the dir entry itself */
+ ValuePtr = DirEntry+8;
+ }
+
+ if (*LastExifRefdP < ValuePtr+ByteCount){
+ /* Keep track of last byte in the exif header that was
+ actually referenced. That way, we know where the
+ discardable thumbnail data begins.
+ */
+ *LastExifRefdP = ValuePtr+ByteCount;
+ }
+
+ /* Extract useful components of tag */
+ switch(Tag){
+
+ case TAG_MAKE:
+ strncpy(m_exifinfo->CameraMake, (char*)ValuePtr, 31);
+ break;
+
+ case TAG_MODEL:
+ strncpy(m_exifinfo->CameraModel, (char*)ValuePtr, 39);
+ break;
+
+ case TAG_EXIF_VERSION:
+ strncpy(m_exifinfo->Version,(char*)ValuePtr, 4);
+ break;
+
+ case TAG_DATETIME_ORIGINAL:
+ strncpy(m_exifinfo->DateTime, (char*)ValuePtr, 19);
+ break;
+
+ case TAG_USERCOMMENT:
+ // Olympus has this padded with trailing spaces. Remove these first.
+ for (a=ByteCount;;){
+ a--;
+ if (((char*)ValuePtr)[a] == ' '){
+ ((char*)ValuePtr)[a] = '\0';
+ }else{
+ break;
+ }
+ if (a == 0) break;
+ }
+
+ /* Copy the comment */
+ if (memcmp(ValuePtr, "ASCII",5) == 0){
+ for (a=5;a<10;a++){
+ char c;
+ c = ((char*)ValuePtr)[a];
+ if (c != '\0' && c != ' '){
+ strncpy(m_exifinfo->Comments, (char*)ValuePtr+a, 199);
+ break;
+ }
+ }
+
+ }else{
+ strncpy(m_exifinfo->Comments, (char*)ValuePtr, 199);
+ }
+ break;
+
+ case TAG_FNUMBER:
+ /* Simplest way of expressing aperture, so I trust it the most.
+ (overwrite previously computd value if there is one)
+ */
+ m_exifinfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_APERTURE:
+ case TAG_MAXAPERTURE:
+ /* More relevant info always comes earlier, so only
+ use this field if we don't have appropriate aperture
+ information yet.
+ */
+ if (m_exifinfo->ApertureFNumber == 0){
+ m_exifinfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)*0.5);
+ }
+ break;
+
+ case TAG_BRIGHTNESS:
+ m_exifinfo->Brightness = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_FOCALLENGTH:
+ /* Nice digital cameras actually save the focal length
+ as a function of how farthey are zoomed in.
+ */
+
+ m_exifinfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_SUBJECT_DISTANCE:
+ /* Inidcates the distacne the autofocus camera is focused to.
+ Tends to be less accurate as distance increases.
+ */
+ m_exifinfo->Distance = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_EXPOSURETIME:
+ /* Simplest way of expressing exposure time, so I
+ trust it most. (overwrite previously computd value
+ if there is one)
+ */
+ m_exifinfo->ExposureTime =
+ (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_SHUTTERSPEED:
+ /* More complicated way of expressing exposure time,
+ so only use this value if we don't already have it
+ from somewhere else.
+ */
+ if (m_exifinfo->ExposureTime == 0){
+ m_exifinfo->ExposureTime = (float)
+ (1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0f)));
+ }
+ break;
+
+ case TAG_FLASH:
+ if ((int32_t)ConvertAnyFormat(ValuePtr, Format) & 7){
+ m_exifinfo->FlashUsed = 1;
+ }else{
+ m_exifinfo->FlashUsed = 0;
+ }
+ break;
+
+ case TAG_ORIENTATION:
+ m_exifinfo->Orientation = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ if (m_exifinfo->Orientation < 1 || m_exifinfo->Orientation > 8){
+ strcpy(m_szLastError,"Undefined rotation value");
+ m_exifinfo->Orientation = 0;
+ }
+ break;
+
+ case TAG_EXIF_IMAGELENGTH:
+ case TAG_EXIF_IMAGEWIDTH:
+ /* Use largest of height and width to deal with images
+ that have been rotated to portrait format.
+ */
+ a = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ if (ExifImageWidth < a) ExifImageWidth = a;
+ break;
+
+ case TAG_FOCALPLANEXRES:
+ m_exifinfo->FocalplaneXRes = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_FOCALPLANEYRES:
+ m_exifinfo->FocalplaneYRes = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_RESOLUTIONUNIT:
+ switch((int32_t)ConvertAnyFormat(ValuePtr, Format)){
+ case 1: m_exifinfo->ResolutionUnit = 1.0f; break; /* 1 inch */
+ case 2: m_exifinfo->ResolutionUnit = 1.0f; break;
+ case 3: m_exifinfo->ResolutionUnit = 0.3937007874f; break; /* 1 centimeter*/
+ case 4: m_exifinfo->ResolutionUnit = 0.03937007874f; break; /* 1 millimeter*/
+ case 5: m_exifinfo->ResolutionUnit = 0.00003937007874f; /* 1 micrometer*/
+ }
+ break;
+
+ case TAG_FOCALPLANEUNITS:
+ switch((int32_t)ConvertAnyFormat(ValuePtr, Format)){
+ case 1: m_exifinfo->FocalplaneUnits = 1.0f; break; /* 1 inch */
+ case 2: m_exifinfo->FocalplaneUnits = 1.0f; break;
+ case 3: m_exifinfo->FocalplaneUnits = 0.3937007874f; break; /* 1 centimeter*/
+ case 4: m_exifinfo->FocalplaneUnits = 0.03937007874f; break; /* 1 millimeter*/
+ case 5: m_exifinfo->FocalplaneUnits = 0.00003937007874f; /* 1 micrometer*/
+ }
+ break;
+
+ // Remaining cases contributed by: Volker C. Schoech <schoech(at)gmx(dot)de>
+
+ case TAG_EXPOSURE_BIAS:
+ m_exifinfo->ExposureBias = (float) ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_WHITEBALANCE:
+ m_exifinfo->Whitebalance = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_METERING_MODE:
+ m_exifinfo->MeteringMode = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_EXPOSURE_PROGRAM:
+ m_exifinfo->ExposureProgram = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_ISO_EQUIVALENT:
+ m_exifinfo->ISOequivalent = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ if ( m_exifinfo->ISOequivalent < 50 ) m_exifinfo->ISOequivalent *= 200;
+ break;
+
+ case TAG_COMPRESSION_LEVEL:
+ m_exifinfo->CompressionLevel = (int32_t)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_XRESOLUTION:
+ m_exifinfo->Xresolution = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+ case TAG_YRESOLUTION:
+ m_exifinfo->Yresolution = (float)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_THUMBNAIL_OFFSET:
+ ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ case TAG_THUMBNAIL_LENGTH:
+ ThumbnailSize = (unsigned)ConvertAnyFormat(ValuePtr, Format);
+ break;
+
+ }
+
+ if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
+ uint8_t * SubdirStart;
+ unsigned Offset = Get32u(ValuePtr);
+ if (Offset>8){
+ SubdirStart = OffsetBase + Offset;
+ if (SubdirStart < OffsetBase ||
+ SubdirStart > OffsetBase+ExifLength){
+ strcpy(m_szLastError,"Illegal subdirectory link");
+ return false;
+ }
+ ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
+ }
+ continue;
+ }
+ }
+
+
+ {
+ /* In addition to linking to subdirectories via exif tags,
+ there's also a potential link to another directory at the end
+ of each directory. This has got to be the result of a
+ committee!
+ */
+ uint8_t * SubdirStart;
+ unsigned Offset;
+ Offset = Get16u(DirStart+2+12*NumDirEntries);
+ if (Offset){
+ SubdirStart = OffsetBase + Offset;
+ if (SubdirStart < OffsetBase
+ || SubdirStart > OffsetBase+ExifLength){
+ strcpy(m_szLastError,"Illegal subdirectory link");
+ return false;
+ }
+ ProcessExifDir(SubdirStart, OffsetBase, ExifLength, m_exifinfo, LastExifRefdP, NestingLevel+1);
+ }
+ }
+
+
+ if (ThumbnailSize && ThumbnailOffset){
+ if (ThumbnailSize + ThumbnailOffset <= ExifLength){
+ /* The thumbnail pointer appears to be valid. Store it. */
+ m_exifinfo->ThumbnailPointer = OffsetBase + ThumbnailOffset;
+ m_exifinfo->ThumbnailSize = ThumbnailSize;
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/*--------------------------------------------------------------------------
+ Evaluate number, be it int32_t, rational, or float from directory.
+--------------------------------------------------------------------------*/
+double CxImageJPG::CxExifInfo::ConvertAnyFormat(void * ValuePtr, int32_t Format)
+{
+ double Value;
+ Value = 0;
+
+ switch(Format){
+ case FMT_SBYTE: Value = *(signed char *)ValuePtr; break;
+ case FMT_BYTE: Value = *(uint8_t *)ValuePtr; break;
+
+ case FMT_USHORT: Value = Get16u(ValuePtr); break;
+ case FMT_ULONG: Value = Get32u(ValuePtr); break;
+
+ case FMT_URATIONAL:
+ case FMT_SRATIONAL:
+ {
+ int32_t Num,Den;
+ Num = Get32s(ValuePtr);
+ Den = Get32s(4+(char *)ValuePtr);
+ if (Den == 0){
+ Value = 0;
+ }else{
+ Value = (double)Num/Den;
+ }
+ break;
+ }
+
+ case FMT_SSHORT: Value = (int16_t)Get16u(ValuePtr); break;
+ case FMT_SLONG: Value = Get32s(ValuePtr); break;
+
+ /* Not sure if this is correct (never seen float used in Exif format)
+ */
+ case FMT_SINGLE: Value = (double)*(float *)ValuePtr; break;
+ case FMT_DOUBLE: Value = *(double *)ValuePtr; break;
+ }
+ return Value;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageJPG::CxExifInfo::process_COM (const uint8_t * Data, int32_t length)
+{
+ int32_t ch;
+ char Comment[MAX_COMMENT+1];
+ int32_t nch;
+ int32_t a;
+
+ nch = 0;
+
+ if (length > MAX_COMMENT) length = MAX_COMMENT; // Truncate if it won't fit in our structure.
+
+ for (a=2;a<length;a++){
+ ch = Data[a];
+
+ if (ch == '\r' && Data[a+1] == '\n') continue; // Remove cr followed by lf.
+
+ if (isprint(ch) || ch == '\n' || ch == '\t'){
+ Comment[nch++] = (char)ch;
+ }else{
+ Comment[nch++] = '?';
+ }
+ }
+
+ Comment[nch] = '\0'; // Null terminate
+
+ //if (ShowTags) printf("COM marker comment: %s\n",Comment);
+
+ strcpy(m_exifinfo->Comments,Comment);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageJPG::CxExifInfo::process_SOFn (const uint8_t * Data, int32_t marker)
+{
+ int32_t data_precision, num_components;
+
+ data_precision = Data[2];
+ m_exifinfo->Height = Get16m((void*)(Data+3));
+ m_exifinfo->Width = Get16m((void*)(Data+5));
+ num_components = Data[7];
+
+ if (num_components == 3){
+ m_exifinfo->IsColor = 1;
+ }else{
+ m_exifinfo->IsColor = 0;
+ }
+
+ m_exifinfo->Process = marker;
+
+ //if (ShowTags) printf("JPEG image is %uw * %uh, %d color components, %d bits per sample\n",
+ // ImageInfo.Width, ImageInfo.Height, num_components, data_precision);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * this will work only on a CxImageJPG object, if the image originally has valid EXIF data
+ \verbatim
+ CxImageJPG jpg;
+ CxIOFile in,out;
+ in.Open("D:\\exif_in.jpg","rb");
+ out.Open("D:\\exif_out.jpg","w+b");
+ jpg.Decode(&in);
+ if (jpg.IsValid()){
+ jpg.RotateLeft();
+ jpg.Encode(&out);
+ }
+ \endverbatim
+*/
+bool CxImageJPG::CxExifInfo::EncodeExif(CxFile * hFile)
+{
+ int32_t a;
+
+ if (FindSection(M_SOS)==NULL){
+ strcpy(m_szLastError,"Can't write exif : didn't read all");
+ return false;
+ }
+
+ // Initial static jpeg marker.
+ hFile->PutC(0xff);
+ hFile->PutC(0xd8);
+
+ if (Sections[0].Type != M_EXIF && Sections[0].Type != M_JFIF){
+ // The image must start with an exif or jfif marker. If we threw those away, create one.
+ static uint8_t JfifHead[18] = {
+ 0xff, M_JFIF,
+ 0x00, 0x10, 'J' , 'F' , 'I' , 'F' , 0x00, 0x01,
+ 0x01, 0x01, 0x01, 0x2C, 0x01, 0x2C, 0x00, 0x00
+ };
+ hFile->Write(JfifHead, 18, 1);
+ }
+
+ // Write all the misc sections
+ for (a=0;a<SectionsRead-1;a++){
+ hFile->PutC(0xff);
+ hFile->PutC((uint8_t)(Sections[a].Type));
+ hFile->Write(Sections[a].Data, Sections[a].Size, 1);
+ }
+
+ // Write the remaining image data.
+ hFile->Write(Sections[a].Data, Sections[a].Size, 1);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageJPG::CxExifInfo::DiscardAllButExif()
+{
+ Section_t ExifKeeper;
+ Section_t CommentKeeper;
+ int32_t a;
+
+ memset(&ExifKeeper, 0, sizeof(ExifKeeper));
+ memset(&CommentKeeper, 0, sizeof(ExifKeeper));
+
+ for (a=0;a<SectionsRead;a++){
+ if (Sections[a].Type == M_EXIF && ExifKeeper.Type == 0){
+ ExifKeeper = Sections[a];
+ }else if (Sections[a].Type == M_COM && CommentKeeper.Type == 0){
+ CommentKeeper = Sections[a];
+ }else{
+ free(Sections[a].Data);
+ Sections[a].Data = 0;
+ }
+ }
+ SectionsRead = 0;
+ if (ExifKeeper.Type){
+ Sections[SectionsRead++] = ExifKeeper;
+ }
+ if (CommentKeeper.Type){
+ Sections[SectionsRead++] = CommentKeeper;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void* CxImageJPG::CxExifInfo::FindSection(int32_t SectionType)
+{
+ int32_t a;
+ for (a=0;a<SectionsRead-1;a++){
+ if (Sections[a].Type == SectionType){
+ return &Sections[a];
+ }
+ }
+ // Could not be found.
+ return NULL;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGEJPG_SUPPORT_EXIF
diff --git a/archive/hge/CxImage/ximage.cpp b/archive/hge/CxImage/ximage.cpp new file mode 100644 index 0000000..904b807 --- /dev/null +++ b/archive/hge/CxImage/ximage.cpp @@ -0,0 +1,537 @@ +// ximage.cpp : main implementation file
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// CxImage
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Initialize the internal structures
+ */
+void CxImage::Startup(uint32_t imagetype)
+{
+ //init pointers
+ pDib = pSelection = pAlpha = NULL;
+ ppLayers = ppFrames = NULL;
+ //init structures
+ memset(&head,0,sizeof(BITMAPINFOHEADER));
+ memset(&info,0,sizeof(CXIMAGEINFO));
+ //init default attributes
+ info.dwType = imagetype;
+ info.fQuality = 90.0f;
+ info.nAlphaMax = 255;
+ info.nBkgndIndex = -1;
+ info.bEnabled = true;
+ info.nJpegScale = 1;
+ SetXDPI(CXIMAGE_DEFAULT_DPI);
+ SetYDPI(CXIMAGE_DEFAULT_DPI);
+
+ int16_t test = 1;
+ info.bLittleEndianHost = (*((char *) &test) == 1);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Empty image constructor
+ * \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
+ */
+CxImage::CxImage(uint32_t imagetype)
+{
+ Startup(imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Call this function to destroy image pixels, alpha channel, selection and sub layers.
+ * - Attributes are not erased, but IsValid returns false.
+ *
+ * \return true if everything is freed, false if the image is a Ghost
+ */
+bool CxImage::Destroy()
+{
+ //free this only if it's valid and it's not a ghost
+ if (info.pGhost==NULL){
+ if (ppLayers) {
+ for(int32_t n=0; n<info.nNumLayers;n++){ delete ppLayers[n]; }
+ delete [] ppLayers; ppLayers=0; info.nNumLayers = 0;
+ }
+ if (pSelection) {free(pSelection); pSelection=0;}
+ if (pAlpha) {free(pAlpha); pAlpha=0;}
+ if (pDib) {free(pDib); pDib=0;}
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::DestroyFrames()
+{
+ if (info.pGhost==NULL) {
+ if (ppFrames) {
+ for (int32_t n=0; n<info.nNumFrames; n++) { delete ppFrames[n]; }
+ delete [] ppFrames; ppFrames = NULL; info.nNumFrames = 0;
+ }
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sized image constructor
+ * \param dwWidth: width
+ * \param dwHeight: height
+ * \param wBpp: bit per pixel, can be 1, 4, 8, 24
+ * \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
+ */
+CxImage::CxImage(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype)
+{
+ Startup(imagetype);
+ Create(dwWidth,dwHeight,wBpp,imagetype);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * image constructor from existing source
+ * \param src: source image.
+ * \param copypixels: copy the pixels from the source image into the new image.
+ * \param copyselection: copy the selection from source
+ * \param copyalpha: copy the alpha channel from source
+ * \sa Copy
+ */
+CxImage::CxImage(const CxImage &src, bool copypixels, bool copyselection, bool copyalpha)
+{
+ Startup(src.GetType());
+ Copy(src,copypixels,copyselection,copyalpha);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Copies the image from an exsisting source
+ * \param src: source image.
+ * \param copypixels: copy the pixels from the source image into the new image.
+ * \param copyselection: copy the selection from source
+ * \param copyalpha: copy the alpha channel from source
+ */
+void CxImage::Copy(const CxImage &src, bool copypixels, bool copyselection, bool copyalpha)
+{
+ // if the source is a ghost, the copy is still a ghost
+ if (src.info.pGhost){
+ Ghost(&src);
+ return;
+ }
+ //copy the attributes
+ memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
+ memcpy(&head,&src.head,sizeof(BITMAPINFOHEADER)); // [andy] - fix for bitmap header DPI
+ //rebuild the image
+ Create(src.GetWidth(),src.GetHeight(),src.GetBpp(),src.GetType());
+ //copy the pixels and the palette, or at least copy the palette only.
+ if (copypixels && pDib && src.pDib) memcpy(pDib,src.pDib,GetSize());
+ else SetPalette(src.GetPalette());
+ int32_t nSize = head.biWidth * head.biHeight;
+ //copy the selection
+ if (copyselection && src.pSelection){
+ if (pSelection) free(pSelection);
+ pSelection = (uint8_t*)malloc(nSize);
+ memcpy(pSelection,src.pSelection,nSize);
+ }
+ //copy the alpha channel
+ if (copyalpha && src.pAlpha){
+ if (pAlpha) free(pAlpha);
+ pAlpha = (uint8_t*)malloc(nSize);
+ memcpy(pAlpha,src.pAlpha,nSize);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Copies the image attributes from an existing image.
+ * - Works only on an empty image, and the image will be still empty.
+ * - <b> Use it before Create() </b>
+ */
+void CxImage::CopyInfo(const CxImage &src)
+{
+ if (pDib==NULL) memcpy(&info,&src.info,sizeof(CXIMAGEINFO));
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa Copy
+ */
+CxImage& CxImage::operator = (const CxImage& isrc)
+{
+ if (this != &isrc) Copy(isrc);
+ return *this;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Initializes or rebuilds the image.
+ * \param dwWidth: width
+ * \param dwHeight: height
+ * \param wBpp: bit per pixel, can be 1, 4, 8, 24
+ * \param imagetype: (optional) set the image format, see ENUM_CXIMAGE_FORMATS
+ * \return pointer to the internal pDib object; NULL if an error occurs.
+ */
+void* CxImage::Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype)
+{
+ // destroy the existing image (if any)
+ if (!Destroy())
+ return NULL;
+
+ // prevent further actions if width or height are not vaild <Balabasnia>
+ if ((dwWidth == 0) || (dwHeight == 0)){
+ strcpy(info.szLastError,"CxImage::Create : width and height must be greater than zero");
+ return NULL;
+ }
+
+ // Make sure bits per pixel is valid
+ if (wBpp <= 1) wBpp = 1;
+ else if (wBpp <= 4) wBpp = 4;
+ else if (wBpp <= 8) wBpp = 8;
+ else wBpp = 24;
+
+ // limit memory requirements
+ if ((((float)dwWidth*(float)dwHeight*(float)wBpp)/8.0f) > (float)CXIMAGE_MAX_MEMORY)
+ {
+ strcpy(info.szLastError,"CXIMAGE_MAX_MEMORY exceeded");
+ return NULL;
+ }
+
+ // set the correct bpp value
+ switch (wBpp){
+ case 1:
+ head.biClrUsed = 2; break;
+ case 4:
+ head.biClrUsed = 16; break;
+ case 8:
+ head.biClrUsed = 256; break;
+ default:
+ head.biClrUsed = 0;
+ }
+
+ //set the common image informations
+ info.dwEffWidth = ((((wBpp * dwWidth) + 31) / 32) * 4);
+ info.dwType = imagetype;
+
+ // initialize BITMAPINFOHEADER
+ head.biSize = sizeof(BITMAPINFOHEADER); //<ralphw>
+ head.biWidth = dwWidth; // fill in width from parameter
+ head.biHeight = dwHeight; // fill in height from parameter
+ head.biPlanes = 1; // must be 1
+ head.biBitCount = (uint16_t)wBpp; // from parameter
+ head.biCompression = BI_RGB;
+ head.biSizeImage = info.dwEffWidth * dwHeight;
+// head.biXPelsPerMeter = 0; See SetXDPI
+// head.biYPelsPerMeter = 0; See SetYDPI
+// head.biClrImportant = 0; See SetClrImportant
+
+ pDib = malloc(GetSize()); // alloc memory block to store our bitmap
+ if (!pDib){
+ strcpy(info.szLastError,"CxImage::Create can't allocate memory");
+ return NULL;
+ }
+
+ //clear the palette
+ RGBQUAD* pal=GetPalette();
+ if (pal) memset(pal,0,GetPaletteSize());
+ //Destroy the existing selection
+#if CXIMAGE_SUPPORT_SELECTION
+ if (pSelection) SelectionDelete();
+#endif //CXIMAGE_SUPPORT_SELECTION
+ //Destroy the existing alpha channel
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha) AlphaDelete();
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ // use our bitmap info structure to fill in first part of
+ // our DIB with the BITMAPINFOHEADER
+ BITMAPINFOHEADER* lpbi;
+ lpbi = (BITMAPINFOHEADER*)(pDib);
+ *lpbi = head;
+
+ info.pImage=GetBits();
+
+ return pDib; //return handle to the DIB
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return pointer to the image pixels. <b> USE CAREFULLY </b>
+ */
+uint8_t* CxImage::GetBits(uint32_t row)
+{
+ if (pDib){
+ if (row) {
+ if (row<(uint32_t)head.biHeight){
+ return ((uint8_t*)pDib + *(uint32_t*)pDib + GetPaletteSize() + (info.dwEffWidth * row));
+ } else {
+ return NULL;
+ }
+ } else {
+ return ((uint8_t*)pDib + *(uint32_t*)pDib + GetPaletteSize());
+ }
+ }
+ return NULL;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return the size in bytes of the internal pDib object
+ */
+int32_t CxImage::GetSize()
+{
+ return head.biSize + head.biSizeImage + GetPaletteSize();
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the coordinates are inside the image
+ * \return true if x and y are both inside the image
+ */
+bool CxImage::IsInside(int32_t x, int32_t y)
+{
+ return (0<=y && y<head.biHeight && 0<=x && x<head.biWidth);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the image bits to the specified value
+ * - for indexed images, the output color is set by the palette entries.
+ * - for RGB images, the output color is a shade of gray.
+ */
+void CxImage::Clear(uint8_t bval)
+{
+ if (pDib == 0) return;
+
+ if (GetBpp() == 1){
+ if (bval > 0) bval = 255;
+ }
+ if (GetBpp() == 4){
+ bval = (uint8_t)(17*(0x0F & bval));
+ }
+
+ memset(info.pImage,bval,head.biSizeImage);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Transfers the image from an existing source image. The source becomes empty.
+ * \return true if everything is ok
+ */
+bool CxImage::Transfer(CxImage &from, bool bTransferFrames /*=true*/)
+{
+ if (!Destroy())
+ return false;
+
+ memcpy(&head,&from.head,sizeof(BITMAPINFOHEADER));
+ memcpy(&info,&from.info,sizeof(CXIMAGEINFO));
+
+ pDib = from.pDib;
+ pSelection = from.pSelection;
+ pAlpha = from.pAlpha;
+ ppLayers = from.ppLayers;
+
+ memset(&from.head,0,sizeof(BITMAPINFOHEADER));
+ memset(&from.info,0,sizeof(CXIMAGEINFO));
+ from.pDib = from.pSelection = from.pAlpha = NULL;
+ from.ppLayers = NULL;
+
+ if (bTransferFrames){
+ DestroyFrames();
+ ppFrames = from.ppFrames;
+ from.ppFrames = NULL;
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * (this) points to the same pDib owned by (*from), the image remains in (*from)
+ * but (this) has the access to the pixels. <b>Use carefully !!!</b>
+ */
+void CxImage::Ghost(const CxImage *from)
+{
+ if (from){
+ memcpy(&head,&from->head,sizeof(BITMAPINFOHEADER));
+ memcpy(&info,&from->info,sizeof(CXIMAGEINFO));
+ pDib = from->pDib;
+ pSelection = from->pSelection;
+ pAlpha = from->pAlpha;
+ ppLayers = from->ppLayers;
+ ppFrames = from->ppFrames;
+ info.pGhost=(CxImage *)from;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * turns a 16 or 32 bit bitfield image into a RGB image
+ */
+void CxImage::Bitfield2RGB(uint8_t *src, uint32_t redmask, uint32_t greenmask, uint32_t bluemask, uint8_t bpp)
+{
+ switch (bpp){
+ case 16:
+ {
+ uint32_t ns[3]={0,0,0};
+ // compute the number of shift for each mask
+ for (int32_t i=0;i<16;i++){
+ if ((redmask>>i)&0x01) ns[0]++;
+ if ((greenmask>>i)&0x01) ns[1]++;
+ if ((bluemask>>i)&0x01) ns[2]++;
+ }
+ ns[1]+=ns[0]; ns[2]+=ns[1]; ns[0]=8-ns[0]; ns[1]-=8; ns[2]-=8;
+ // dword aligned width for 16 bit image
+ int32_t effwidth2=(((head.biWidth + 1) / 2) * 4);
+ uint16_t w;
+ int32_t y2,y3,x2,x3;
+ uint8_t *p=info.pImage;
+ // scan the buffer in reverse direction to avoid reallocations
+ for (int32_t y=head.biHeight-1; y>=0; y--){
+ y2=effwidth2*y;
+ y3=info.dwEffWidth*y;
+ for (int32_t x=head.biWidth-1; x>=0; x--){
+ x2 = 2*x+y2;
+ x3 = 3*x+y3;
+ w = (uint16_t)(src[x2]+256*src[1+x2]);
+ p[ x3]=(uint8_t)((w & bluemask)<<ns[0]);
+ p[1+x3]=(uint8_t)((w & greenmask)>>ns[1]);
+ p[2+x3]=(uint8_t)((w & redmask)>>ns[2]);
+ }
+ }
+ break;
+ }
+ case 32:
+ {
+ uint32_t ns[3]={0,0,0};
+ // compute the number of shift for each mask
+ for (int32_t i=8;i<32;i+=8){
+ if (redmask>>i) ns[0]++;
+ if (greenmask>>i) ns[1]++;
+ if (bluemask>>i) ns[2]++;
+ }
+ // dword aligned width for 32 bit image
+ int32_t effwidth4 = head.biWidth * 4;
+ int32_t y4,y3,x4,x3;
+ uint8_t *p=info.pImage;
+ // scan the buffer in reverse direction to avoid reallocations
+ for (int32_t y=head.biHeight-1; y>=0; y--){
+ y4=effwidth4*y;
+ y3=info.dwEffWidth*y;
+ for (int32_t x=head.biWidth-1; x>=0; x--){
+ x4 = 4*x+y4;
+ x3 = 3*x+y3;
+ p[ x3]=src[ns[2]+x4];
+ p[1+x3]=src[ns[1]+x4];
+ p[2+x3]=src[ns[0]+x4];
+ }
+ }
+ }
+
+ }
+ return;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Creates an image from a generic buffer
+ * \param pArray: source memory buffer
+ * \param dwWidth: image width
+ * \param dwHeight: image height
+ * \param dwBitsperpixel: can be 1,4,8,24,32
+ * \param dwBytesperline: line alignment, in bytes, for a single row stored in pArray
+ * \param bFlipImage: tune this parameter if the image is upsidedown
+ * \return true if everything is ok
+ */
+bool CxImage::CreateFromArray(uint8_t* pArray,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage)
+{
+ if (pArray==NULL) return false;
+ if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)||
+ (dwBitsperpixel==24)||(dwBitsperpixel==32))) return false;
+
+ if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false;
+
+ if (dwBitsperpixel<24) SetGrayPalette();
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (dwBitsperpixel==32) AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ uint8_t *dst,*src;
+
+ for (uint32_t y = 0; y<dwHeight; y++) {
+ dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
+ src = pArray + y * dwBytesperline;
+ if (dwBitsperpixel==32){
+ for(uint32_t x=0;x<dwWidth;x++){
+ *dst++=src[0];
+ *dst++=src[1];
+ *dst++=src[2];
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaSet(x,(bFlipImage?(dwHeight-1-y):y),src[3]);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ src+=4;
+ }
+ } else {
+ memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa CreateFromArray
+ */
+bool CxImage::CreateFromMatrix(uint8_t** ppMatrix,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage)
+{
+ if (ppMatrix==NULL) return false;
+ if (!((dwBitsperpixel==1)||(dwBitsperpixel==4)||(dwBitsperpixel==8)||
+ (dwBitsperpixel==24)||(dwBitsperpixel==32))) return false;
+
+ if (!Create(dwWidth,dwHeight,dwBitsperpixel)) return false;
+
+ if (dwBitsperpixel<24) SetGrayPalette();
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (dwBitsperpixel==32) AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ uint8_t *dst,*src;
+
+ for (uint32_t y = 0; y<dwHeight; y++) {
+ dst = info.pImage + (bFlipImage?(dwHeight-1-y):y) * info.dwEffWidth;
+ src = ppMatrix[y];
+ if (src){
+ if (dwBitsperpixel==32){
+ for(uint32_t x=0;x<dwWidth;x++){
+ *dst++=src[0];
+ *dst++=src[1];
+ *dst++=src[2];
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaSet(x,(bFlipImage?(dwHeight-1-y):y),src[3]);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ src+=4;
+ }
+ } else {
+ memcpy(dst,src,min(info.dwEffWidth,dwBytesperline));
+ }
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return lightness difference between elem1 and elem2
+ */
+int32_t CxImage::CompareColors(const void *elem1, const void *elem2)
+{
+ RGBQUAD* c1 = (RGBQUAD*)elem1;
+ RGBQUAD* c2 = (RGBQUAD*)elem2;
+
+ int32_t g1 = (int32_t)RGB2GRAY(c1->rgbRed,c1->rgbGreen,c1->rgbBlue);
+ int32_t g2 = (int32_t)RGB2GRAY(c2->rgbRed,c2->rgbGreen,c2->rgbBlue);
+
+ return (g1-g2);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * simply calls "if (memblock) free(memblock);".
+ * Useful when calling Encode for a memory buffer,
+ * from a DLL compiled with different memory management options.
+ * CxImage::FreeMemory will use the same memory environment used by Encode.
+ * \author [livecn]
+ */
+void CxImage::FreeMemory(void* memblock)
+{
+ if (memblock)
+ free(memblock);
+}
+////////////////////////////////////////////////////////////////////////////////
+//EOF
diff --git a/archive/hge/CxImage/ximage.h b/archive/hge/CxImage/ximage.h new file mode 100644 index 0000000..4eed84e --- /dev/null +++ b/archive/hge/CxImage/ximage.h @@ -0,0 +1,808 @@ +/*
+ * File: ximage.h
+ * Purpose: General Purpose Image Class
+ */
+/*
+ --------------------------------------------------------------------------------
+
+ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+ CxImage version 7.0.0 31/Dec/2010
+
+ CxImage : Copyright (C) 2001 - 2010, Davide Pizzolato
+
+ Original CImage and CImageIterator implementation are:
+ Copyright (C) 1995, Alejandro Aguilar Sierra (asierra(at)servidor(dot)unam(dot)mx)
+
+ Covered code is provided under this license on an "as is" basis, without warranty
+ of any kind, either expressed or implied, including, without limitation, warranties
+ that the covered code is free of defects, merchantable, fit for a particular purpose
+ or non-infringing. The entire risk as to the quality and performance of the covered
+ code is with you. Should any covered code prove defective in any respect, you (not
+ the initial developer or any other contributor) assume the cost of any necessary
+ servicing, repair or correction. This disclaimer of warranty constitutes an essential
+ part of this license. No use of any covered code is authorized hereunder except under
+ this disclaimer.
+
+ Permission is hereby granted to use, copy, modify, and distribute this
+ source code, or portions hereof, for any purpose, including commercial applications,
+ freely and without fee, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ --------------------------------------------------------------------------------
+
+ Other information about CxImage, and the latest version, can be found at the
+ CxImage home page: http://www.xdp.it/cximage/
+
+ --------------------------------------------------------------------------------
+ */
+#if !defined(__CXIMAGE_H)
+#define __CXIMAGE_H
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+#ifdef _LINUX
+#ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE
+#endif
+ #include <unistd.h>
+ #include <arpa/inet.h>
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#include "xfile.h"
+#include "xiofile.h"
+#include "xmemfile.h"
+#include "ximadef.h" //<vho> adjust some #define
+
+/* see "ximacfg.h" for CxImage configuration options */
+
+/////////////////////////////////////////////////////////////////////////////
+// CxImage formats enumerator
+enum ENUM_CXIMAGE_FORMATS{
+CXIMAGE_FORMAT_UNKNOWN = 0,
+#if CXIMAGE_SUPPORT_BMP
+CXIMAGE_FORMAT_BMP = 1,
+#endif
+#if CXIMAGE_SUPPORT_GIF
+CXIMAGE_FORMAT_GIF = 2,
+#endif
+#if CXIMAGE_SUPPORT_JPG
+CXIMAGE_FORMAT_JPG = 3,
+#endif
+#if CXIMAGE_SUPPORT_PNG
+CXIMAGE_FORMAT_PNG = 4,
+#endif
+#if CXIMAGE_SUPPORT_ICO
+CXIMAGE_FORMAT_ICO = 5,
+#endif
+#if CXIMAGE_SUPPORT_TIF
+CXIMAGE_FORMAT_TIF = 6,
+#endif
+#if CXIMAGE_SUPPORT_TGA
+CXIMAGE_FORMAT_TGA = 7,
+#endif
+#if CXIMAGE_SUPPORT_PCX
+CXIMAGE_FORMAT_PCX = 8,
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+CXIMAGE_FORMAT_WBMP = 9,
+#endif
+#if CXIMAGE_SUPPORT_WMF
+CXIMAGE_FORMAT_WMF = 10,
+#endif
+#if CXIMAGE_SUPPORT_JP2
+CXIMAGE_FORMAT_JP2 = 11,
+#endif
+#if CXIMAGE_SUPPORT_JPC
+CXIMAGE_FORMAT_JPC = 12,
+#endif
+#if CXIMAGE_SUPPORT_PGX
+CXIMAGE_FORMAT_PGX = 13,
+#endif
+#if CXIMAGE_SUPPORT_PNM
+CXIMAGE_FORMAT_PNM = 14,
+#endif
+#if CXIMAGE_SUPPORT_RAS
+CXIMAGE_FORMAT_RAS = 15,
+#endif
+#if CXIMAGE_SUPPORT_JBG
+CXIMAGE_FORMAT_JBG = 16,
+#endif
+#if CXIMAGE_SUPPORT_MNG
+CXIMAGE_FORMAT_MNG = 17,
+#endif
+#if CXIMAGE_SUPPORT_SKA
+CXIMAGE_FORMAT_SKA = 18,
+#endif
+#if CXIMAGE_SUPPORT_RAW
+CXIMAGE_FORMAT_RAW = 19,
+#endif
+#if CXIMAGE_SUPPORT_PSD
+CXIMAGE_FORMAT_PSD = 20,
+#endif
+CMAX_IMAGE_FORMATS = CXIMAGE_SUPPORT_BMP + CXIMAGE_SUPPORT_GIF + CXIMAGE_SUPPORT_JPG +
+ CXIMAGE_SUPPORT_PNG + CXIMAGE_SUPPORT_MNG + CXIMAGE_SUPPORT_ICO +
+ CXIMAGE_SUPPORT_TIF + CXIMAGE_SUPPORT_TGA + CXIMAGE_SUPPORT_PCX +
+ CXIMAGE_SUPPORT_WBMP+ CXIMAGE_SUPPORT_WMF +
+ CXIMAGE_SUPPORT_JBG + CXIMAGE_SUPPORT_JP2 + CXIMAGE_SUPPORT_JPC +
+ CXIMAGE_SUPPORT_PGX + CXIMAGE_SUPPORT_PNM + CXIMAGE_SUPPORT_RAS +
+ CXIMAGE_SUPPORT_SKA + CXIMAGE_SUPPORT_RAW + CXIMAGE_SUPPORT_PSD + 1
+};
+
+#if CXIMAGE_SUPPORT_EXIF
+
+#define MAX_COMMENT 255
+#define MAX_SECTIONS 20
+
+typedef struct tag_ExifInfo {
+ char Version [5];
+ char CameraMake [32];
+ char CameraModel [40];
+ char DateTime [20];
+ int32_t Height, Width;
+ int32_t Orientation;
+ int32_t IsColor;
+ int32_t Process;
+ int32_t FlashUsed;
+ float FocalLength;
+ float ExposureTime;
+ float ApertureFNumber;
+ float Distance;
+ float CCDWidth;
+ float ExposureBias;
+ int32_t Whitebalance;
+ int32_t MeteringMode;
+ int32_t ExposureProgram;
+ int32_t ISOequivalent;
+ int32_t CompressionLevel;
+ float FocalplaneXRes;
+ float FocalplaneYRes;
+ float FocalplaneUnits;
+ float Xresolution;
+ float Yresolution;
+ float ResolutionUnit;
+ float Brightness;
+ char Comments[MAX_COMMENT+1];
+
+ uint8_t * ThumbnailPointer; /* Pointer at the thumbnail */
+ unsigned ThumbnailSize; /* Size of thumbnail. */
+
+ bool IsExif;
+} EXIFINFO;
+
+#endif //CXIMAGE_SUPPORT_EXIF
+
+/////////////////////////////////////////////////////////////////////////////
+// CxImage class
+/////////////////////////////////////////////////////////////////////////////
+class DLL_EXP CxImage
+{
+//extensible information collector
+typedef struct tagCxImageInfo {
+ uint32_t dwEffWidth; ///< uint32_t aligned scan line width
+ uint8_t* pImage; ///< THE IMAGE BITS
+ CxImage* pGhost; ///< if this is a ghost, pGhost points to the body
+ CxImage* pParent; ///< if this is a layer, pParent points to the body
+ uint32_t dwType; ///< original image format
+ char szLastError[256]; ///< debugging
+ int32_t nProgress; ///< monitor
+ int32_t nEscape; ///< escape
+ int32_t nBkgndIndex; ///< used for GIF, PNG, MNG
+ RGBQUAD nBkgndColor; ///< used for RGB transparency
+ float fQuality; ///< used for JPEG, JPEG2000 (0.0f ... 100.0f)
+ uint8_t nJpegScale; ///< used for JPEG [ignacio]
+ int32_t nFrame; ///< used for TIF, GIF, MNG : actual frame
+ int32_t nNumFrames; ///< used for TIF, GIF, MNG : total number of frames
+ uint32_t dwFrameDelay; ///< used for GIF, MNG
+ int32_t xDPI; ///< horizontal resolution
+ int32_t yDPI; ///< vertical resolution
+ RECT rSelectionBox; ///< bounding rectangle
+ uint8_t nAlphaMax; ///< max opacity (fade)
+ bool bAlphaPaletteEnabled; ///< true if alpha values in the palette are enabled.
+ bool bEnabled; ///< enables the painting functions
+ int32_t xOffset;
+ int32_t yOffset;
+ uint32_t dwCodecOpt[CMAX_IMAGE_FORMATS]; ///< for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg
+ RGBQUAD last_c; ///< for GetNearestIndex optimization
+ uint8_t last_c_index;
+ bool last_c_isvalid;
+ int32_t nNumLayers;
+ uint32_t dwFlags; ///< 0x??00000 = reserved, 0x00??0000 = blend mode, 0x0000???? = layer id - user flags
+ uint8_t dispmeth;
+ bool bGetAllFrames;
+ bool bLittleEndianHost;
+
+#if CXIMAGE_SUPPORT_EXIF
+ EXIFINFO ExifInfo;
+#endif
+
+} CXIMAGEINFO;
+
+public:
+ //public structures
+struct rgb_color { uint8_t r,g,b; };
+
+#if CXIMAGE_SUPPORT_WINDOWS
+// <VATI> text placement data
+// members must be initialized with the InitTextInfo(&this) function.
+typedef struct tagCxTextInfo
+{
+#if defined (_WIN32_WCE)
+ TCHAR text[256]; ///< text for windows CE
+#else
+ TCHAR text[4096]; ///< text (char -> TCHAR for UNICODE [Cesar M])
+#endif
+ LOGFONT lfont; ///< font and codepage data
+ COLORREF fcolor; ///< foreground color
+ int32_t align; ///< DT_CENTER, DT_RIGHT, DT_LEFT aligment for multiline text
+ uint8_t smooth; ///< text smoothing option. Default is false.
+ uint8_t opaque; ///< text has background or hasn't. Default is true.
+ ///< data for background (ignored if .opaque==FALSE)
+ COLORREF bcolor; ///< background color
+ float b_opacity; ///< opacity value for background between 0.0-1.0 Default is 0. (opaque)
+ uint8_t b_outline; ///< outline width for background (zero: no outline)
+ uint8_t b_round; ///< rounding radius for background rectangle. % of the height, between 0-50. Default is 10.
+ ///< (backgr. always has a frame: width = 3 pixel + 10% of height by default.)
+} CXTEXTINFO;
+#endif
+
+public:
+/** \addtogroup Constructors */ //@{
+ CxImage(uint32_t imagetype = 0);
+ CxImage(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0);
+ CxImage(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
+#if CXIMAGE_SUPPORT_DECODE
+ CxImage(const TCHAR * filename, uint32_t imagetype); // For UNICODE support: char -> TCHAR
+ CxImage(FILE * stream, uint32_t imagetype);
+ CxImage(CxFile * stream, uint32_t imagetype);
+ CxImage(uint8_t * buffer, uint32_t size, uint32_t imagetype);
+#endif
+ virtual ~CxImage() { DestroyFrames(); Destroy(); };
+ CxImage& operator = (const CxImage&);
+//@}
+
+/** \addtogroup Initialization */ //@{
+ void* Create(uint32_t dwWidth, uint32_t dwHeight, uint32_t wBpp, uint32_t imagetype = 0);
+ bool Destroy();
+ bool DestroyFrames();
+ void Clear(uint8_t bval=0);
+ void Copy(const CxImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);
+ bool Transfer(CxImage &from, bool bTransferFrames = true);
+ bool CreateFromArray(uint8_t* pArray,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage);
+ bool CreateFromMatrix(uint8_t** ppMatrix,uint32_t dwWidth,uint32_t dwHeight,uint32_t dwBitsperpixel, uint32_t dwBytesperline, bool bFlipImage);
+ void FreeMemory(void* memblock);
+
+ uint32_t Dump(uint8_t * dst);
+ uint32_t UnDump(const uint8_t * src);
+ uint32_t DumpSize();
+
+//@}
+
+/** \addtogroup Attributes */ //@{
+ int32_t GetSize();
+ uint8_t* GetBits(uint32_t row = 0);
+ uint8_t GetColorType();
+ void* GetDIB() const;
+ uint32_t GetHeight() const;
+ uint32_t GetWidth() const;
+ uint32_t GetEffWidth() const;
+ uint32_t GetNumColors() const;
+ uint16_t GetBpp() const;
+ uint32_t GetType() const;
+ const char* GetLastError();
+ static const TCHAR* GetVersion();
+ static const float GetVersionNumber();
+
+ uint32_t GetFrameDelay() const;
+ void SetFrameDelay(uint32_t d);
+
+ void GetOffset(int32_t *x,int32_t *y);
+ void SetOffset(int32_t x,int32_t y);
+
+ uint8_t GetJpegQuality() const;
+ void SetJpegQuality(uint8_t q);
+ float GetJpegQualityF() const;
+ void SetJpegQualityF(float q);
+
+ uint8_t GetJpegScale() const;
+ void SetJpegScale(uint8_t q);
+
+#if CXIMAGE_SUPPORT_EXIF
+ EXIFINFO *GetExifInfo() {return &info.ExifInfo;};
+ bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t imageType);
+ #if CXIMAGE_SUPPORT_TRANSFORMATION
+ bool RotateExif(int32_t orientation = 0);
+ #endif
+#endif
+
+ int32_t GetXDPI() const;
+ int32_t GetYDPI() const;
+ void SetXDPI(int32_t dpi);
+ void SetYDPI(int32_t dpi);
+
+ uint32_t GetClrImportant() const;
+ void SetClrImportant(uint32_t ncolors = 0);
+
+ int32_t GetProgress() const;
+ int32_t GetEscape() const;
+ void SetProgress(int32_t p);
+ void SetEscape(int32_t i);
+
+ int32_t GetTransIndex() const;
+ RGBQUAD GetTransColor();
+ void SetTransIndex(int32_t idx);
+ void SetTransColor(RGBQUAD rgb);
+ bool IsTransparent() const;
+
+ uint32_t GetCodecOption(uint32_t imagetype = 0);
+ bool SetCodecOption(uint32_t opt, uint32_t imagetype = 0);
+
+ uint32_t GetFlags() const;
+ void SetFlags(uint32_t flags, bool bLockReservedFlags = true);
+
+ uint8_t GetDisposalMethod() const;
+ void SetDisposalMethod(uint8_t dm);
+
+ bool SetType(uint32_t type);
+
+ static uint32_t GetNumTypes();
+ static uint32_t GetTypeIdFromName(const TCHAR* ext);
+ static uint32_t GetTypeIdFromIndex(const uint32_t index);
+ static uint32_t GetTypeIndexFromId(const uint32_t id);
+
+ bool GetRetreiveAllFrames() const;
+ void SetRetreiveAllFrames(bool flag);
+ CxImage * GetFrame(int32_t nFrame) const;
+
+ //void* GetUserData() const {return info.pUserData;}
+ //void SetUserData(void* pUserData) {info.pUserData = pUserData;}
+//@}
+
+/** \addtogroup Palette
+ * These functions have no effects on RGB images and in this case the returned value is always 0.
+ * @{ */
+ bool IsGrayScale();
+ bool IsIndexed() const;
+ bool IsSamePalette(CxImage &img, bool bCheckAlpha = true);
+ uint32_t GetPaletteSize();
+ RGBQUAD* GetPalette() const;
+ RGBQUAD GetPaletteColor(uint8_t idx);
+ bool GetPaletteColor(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b);
+ uint8_t GetNearestIndex(RGBQUAD c);
+ void BlendPalette(COLORREF cr,int32_t perc);
+ void SetGrayPalette();
+ void SetPalette(uint32_t n, uint8_t *r, uint8_t *g, uint8_t *b);
+ void SetPalette(RGBQUAD* pPal,uint32_t nColors=256);
+ void SetPalette(rgb_color *rgb,uint32_t nColors=256);
+ void SetPaletteColor(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t alpha=0);
+ void SetPaletteColor(uint8_t idx, RGBQUAD c);
+ void SetPaletteColor(uint8_t idx, COLORREF cr);
+ void SwapIndex(uint8_t idx1, uint8_t idx2);
+ void SwapRGB2BGR();
+ void SetStdPalette();
+//@}
+
+/** \addtogroup Pixel */ //@{
+ bool IsInside(int32_t x, int32_t y);
+ bool IsTransparent(int32_t x,int32_t y);
+ bool GetTransparentMask(CxImage* iDst = 0);
+ RGBQUAD GetPixelColor(int32_t x,int32_t y, bool bGetAlpha = true);
+ uint8_t GetPixelIndex(int32_t x,int32_t y);
+ uint8_t GetPixelGray(int32_t x, int32_t y);
+ void SetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha = false);
+ void SetPixelColor(int32_t x,int32_t y,COLORREF cr);
+ void SetPixelIndex(int32_t x,int32_t y,uint8_t i);
+ void DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, RGBQUAD color, bool bSetAlpha=false);
+ void DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, COLORREF cr);
+ void BlendPixelColor(int32_t x,int32_t y,RGBQUAD c, float blend, bool bSetAlpha = false);
+//@}
+
+protected:
+/** \addtogroup Protected */ //@{
+ uint8_t BlindGetPixelIndex(const int32_t x,const int32_t y);
+ RGBQUAD BlindGetPixelColor(const int32_t x,const int32_t y, bool bGetAlpha = true);
+ void *BlindGetPixelPointer(const int32_t x,const int32_t y);
+ void BlindSetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha = false);
+ void BlindSetPixelIndex(int32_t x,int32_t y,uint8_t i);
+//@}
+
+public:
+
+#if CXIMAGE_SUPPORT_INTERPOLATION
+/** \addtogroup Interpolation */ //@{
+ //overflow methods:
+ enum OverflowMethod {
+ OM_COLOR=1,
+ OM_BACKGROUND=2,
+ OM_TRANSPARENT=3,
+ OM_WRAP=4,
+ OM_REPEAT=5,
+ OM_MIRROR=6
+ };
+ void OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod);
+ void OverflowCoordinates(int32_t &x, int32_t &y, OverflowMethod const ofMethod);
+ RGBQUAD GetPixelColorWithOverflow(int32_t x, int32_t y, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
+ //interpolation methods:
+ enum InterpolationMethod {
+ IM_NEAREST_NEIGHBOUR=1,
+ IM_BILINEAR =2,
+ IM_BSPLINE =3,
+ IM_BICUBIC =4,
+ IM_BICUBIC2 =5,
+ IM_LANCZOS =6,
+ IM_BOX =7,
+ IM_HERMITE =8,
+ IM_HAMMING =9,
+ IM_SINC =10,
+ IM_BLACKMAN =11,
+ IM_BESSEL =12,
+ IM_GAUSSIAN =13,
+ IM_QUADRATIC =14,
+ IM_MITCHELL =15,
+ IM_CATROM =16,
+ IM_HANNING =17,
+ IM_POWER =18
+ };
+ RGBQUAD GetPixelColorInterpolated(float x,float y, InterpolationMethod const inMethod=IM_BILINEAR, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
+ RGBQUAD GetAreaColorInterpolated(float const xc, float const yc, float const w, float const h, InterpolationMethod const inMethod, OverflowMethod const ofMethod=OM_BACKGROUND, RGBQUAD* const rplColor=0);
+//@}
+
+protected:
+/** \addtogroup Protected */ //@{
+ void AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa);
+//@}
+
+/** \addtogroup Kernels */ //@{
+public:
+ static float KernelBSpline(const float x);
+ static float KernelLinear(const float t);
+ static float KernelCubic(const float t);
+ static float KernelGeneralizedCubic(const float t, const float a=-1);
+ static float KernelLanczosSinc(const float t, const float r = 3);
+ static float KernelBox(const float x);
+ static float KernelHermite(const float x);
+ static float KernelHamming(const float x);
+ static float KernelSinc(const float x);
+ static float KernelBlackman(const float x);
+ static float KernelBessel_J1(const float x);
+ static float KernelBessel_P1(const float x);
+ static float KernelBessel_Q1(const float x);
+ static float KernelBessel_Order1(float x);
+ static float KernelBessel(const float x);
+ static float KernelGaussian(const float x);
+ static float KernelQuadratic(const float x);
+ static float KernelMitchell(const float x);
+ static float KernelCatrom(const float x);
+ static float KernelHanning(const float x);
+ static float KernelPower(const float x, const float a = 2);
+//@}
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+
+/** \addtogroup Painting */ //@{
+#if CXIMAGE_SUPPORT_WINDOWS
+ int32_t Blt(HDC pDC, int32_t x=0, int32_t y=0);
+ HBITMAP Draw2HBITMAP(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy, RECT* pClipRect, bool bSmooth);
+ HBITMAP MakeBitmap(HDC hdc = NULL, bool bTransparency = false);
+ HICON MakeIcon(HDC hdc = NULL, bool bTransparency = false);
+ HANDLE CopyToHandle();
+ bool CreateFromHANDLE(HANDLE hMem); //Windows objects (clipboard)
+ bool CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0, bool bTransparency = false); //Windows resource
+ bool CreateFromHICON(HICON hico, bool bTransparency = false);
+ int32_t Draw(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1, RECT* pClipRect = 0, bool bSmooth = false, bool bFlipY = false);
+ int32_t Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false, bool bFlipY = false);
+ int32_t Stretch(HDC hdc, int32_t xoffset, int32_t yoffset, int32_t xsize, int32_t ysize, uint32_t dwRop = SRCCOPY);
+ int32_t Stretch(HDC hdc, const RECT& rect, uint32_t dwRop = SRCCOPY);
+ int32_t Tile(HDC hdc, RECT *rc);
+ int32_t Draw2(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1);
+ int32_t Draw2(HDC hdc, const RECT& rect);
+ //int32_t DrawString(HDC hdc, int32_t x, int32_t y, const char* text, RGBQUAD color, const char* font, int32_t lSize=0, int32_t lWeight=400, uint8_t bItalic=0, uint8_t bUnderline=0, bool bSetAlpha=false);
+ int32_t DrawString(HDC hdc, int32_t x, int32_t y, const TCHAR* text, RGBQUAD color, const TCHAR* font, int32_t lSize=0, int32_t lWeight=400, uint8_t bItalic=0, uint8_t bUnderline=0, bool bSetAlpha=false);
+ // <VATI> extensions
+ int32_t DrawStringEx(HDC hdc, int32_t x, int32_t y, CXTEXTINFO *pTextType, bool bSetAlpha=false );
+ void InitTextInfo( CXTEXTINFO *txt );
+protected:
+ bool IsHBITMAPAlphaValid( HBITMAP hbmp );
+public:
+#endif //CXIMAGE_SUPPORT_WINDOWS
+//@}
+
+ // file operations
+#if CXIMAGE_SUPPORT_DECODE
+/** \addtogroup Decode */ //@{
+#ifdef WIN32
+ //bool Load(LPCWSTR filename, uint32_t imagetype=0);
+ bool LoadResource(HRSRC hRes, uint32_t imagetype, HMODULE hModule=NULL);
+#endif
+ // For UNICODE support: char -> TCHAR
+ bool Load(const TCHAR* filename, uint32_t imagetype=0);
+ //bool Load(const char * filename, uint32_t imagetype=0);
+ bool Decode(FILE * hFile, uint32_t imagetype);
+ bool Decode(CxFile * hFile, uint32_t imagetype);
+ bool Decode(uint8_t * buffer, uint32_t size, uint32_t imagetype);
+
+ bool CheckFormat(CxFile * hFile, uint32_t imagetype = 0);
+ bool CheckFormat(uint8_t * buffer, uint32_t size, uint32_t imagetype = 0);
+//@}
+#endif //CXIMAGE_SUPPORT_DECODE
+
+#if CXIMAGE_SUPPORT_ENCODE
+protected:
+/** \addtogroup Protected */ //@{
+ bool EncodeSafeCheck(CxFile *hFile);
+//@}
+
+public:
+/** \addtogroup Encode */ //@{
+#ifdef WIN32
+ //bool Save(LPCWSTR filename, uint32_t imagetype=0);
+#endif
+ // For UNICODE support: char -> TCHAR
+ bool Save(const TCHAR* filename, uint32_t imagetype);
+ //bool Save(const char * filename, uint32_t imagetype=0);
+ bool Encode(FILE * hFile, uint32_t imagetype);
+ bool Encode(CxFile * hFile, uint32_t imagetype);
+ bool Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype);
+ bool Encode(FILE *hFile, CxImage ** pImages, int32_t pagecount, uint32_t imagetype);
+ bool Encode(uint8_t * &buffer, int32_t &size, uint32_t imagetype);
+
+ bool Encode2RGBA(CxFile *hFile, bool bFlipY = false);
+ bool Encode2RGBA(uint8_t * &buffer, int32_t &size, bool bFlipY = false);
+//@}
+#endif //CXIMAGE_SUPPORT_ENCODE
+
+/** \addtogroup Attributes */ //@{
+ //misc.
+ bool IsValid() const;
+ bool IsEnabled() const;
+ void Enable(bool enable=true);
+
+ // frame operations
+ int32_t GetNumFrames() const;
+ int32_t GetFrame() const;
+ void SetFrame(int32_t nFrame);
+//@}
+
+#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
+/** \addtogroup BasicTransformations */ //@{
+ bool GrayScale();
+ bool Flip(bool bFlipSelection = false, bool bFlipAlpha = true);
+ bool Mirror(bool bMirrorSelection = false, bool bMirrorAlpha = true);
+ bool Negative();
+ bool RotateLeft(CxImage* iDst = NULL);
+ bool RotateRight(CxImage* iDst = NULL);
+ bool IncreaseBpp(uint32_t nbit);
+//@}
+#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
+
+#if CXIMAGE_SUPPORT_TRANSFORMATION
+/** \addtogroup Transformations */ //@{
+ // image operations
+ bool Rotate(float angle, CxImage* iDst = NULL);
+ bool Rotate2(float angle, CxImage *iDst = NULL, InterpolationMethod inMethod=IM_BILINEAR,
+ OverflowMethod ofMethod=OM_BACKGROUND, RGBQUAD *replColor=0,
+ bool const optimizeRightAngles=true, bool const bKeepOriginalSize=false);
+ bool Rotate180(CxImage* iDst = NULL);
+ bool Resample(int32_t newx, int32_t newy, int32_t mode = 1, CxImage* iDst = NULL);
+ bool Resample2(int32_t newx, int32_t newy, InterpolationMethod const inMethod=IM_BICUBIC2,
+ OverflowMethod const ofMethod=OM_REPEAT, CxImage* const iDst = NULL,
+ bool const disableAveraging=false);
+ bool DecreaseBpp(uint32_t nbit, bool errordiffusion, RGBQUAD* ppal = 0, uint32_t clrimportant = 0);
+ bool Dither(int32_t method = 0);
+ bool Crop(int32_t left, int32_t top, int32_t right, int32_t bottom, CxImage* iDst = NULL);
+ bool Crop(const RECT& rect, CxImage* iDst = NULL);
+ bool CropRotatedRectangle( int32_t topx, int32_t topy, int32_t width, int32_t height, float angle, CxImage* iDst = NULL);
+ bool Skew(float xgain, float ygain, int32_t xpivot=0, int32_t ypivot=0, bool bEnableInterpolation = false);
+ bool Expand(int32_t left, int32_t top, int32_t right, int32_t bottom, RGBQUAD canvascolor, CxImage* iDst = 0);
+ bool Expand(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst = 0);
+ bool Thumbnail(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst = 0);
+ bool CircleTransform(int32_t type,int32_t rmax=0,float Koeff=1.0f);
+ bool QIShrink(int32_t newx, int32_t newy, CxImage* const iDst = NULL, bool bChangeBpp = false);
+
+//@}
+#endif //CXIMAGE_SUPPORT_TRANSFORMATION
+
+#if CXIMAGE_SUPPORT_DSP
+/** \addtogroup DSP */ //@{
+ bool Contour();
+ bool HistogramStretch(int32_t method = 0, double threshold = 0);
+ bool HistogramEqualize();
+ bool HistogramNormalize();
+ bool HistogramRoot();
+ bool HistogramLog();
+ int32_t Histogram(int32_t* red, int32_t* green = 0, int32_t* blue = 0, int32_t* gray = 0, int32_t colorspace = 0);
+ bool Jitter(int32_t radius=2);
+ bool Repair(float radius = 0.25f, int32_t niterations = 1, int32_t colorspace = 0);
+ bool Combine(CxImage* r,CxImage* g,CxImage* b,CxImage* a, int32_t colorspace = 0);
+ bool FFT2(CxImage* srcReal, CxImage* srcImag, CxImage* dstReal, CxImage* dstImag, int32_t direction = 1, bool bForceFFT = true, bool bMagnitude = true);
+ bool Noise(int32_t level);
+ bool Median(int32_t Ksize=3);
+ bool Gamma(float gamma);
+ bool GammaRGB(float gammaR, float gammaG, float gammaB);
+ bool ShiftRGB(int32_t r, int32_t g, int32_t b);
+ bool Threshold(uint8_t level);
+ bool Threshold(CxImage* pThresholdMask);
+ bool Threshold2(uint8_t level, bool bDirection, RGBQUAD nBkgndColor, bool bSetAlpha = false);
+ bool Colorize(uint8_t hue, uint8_t sat, float blend = 1.0f);
+ bool Light(int32_t brightness, int32_t contrast = 0);
+ float Mean();
+ bool Filter(int32_t* kernel, int32_t Ksize, int32_t Kfactor, int32_t Koffset);
+ bool Erode(int32_t Ksize=2);
+ bool Dilate(int32_t Ksize=2);
+ bool Edge(int32_t Ksize=2);
+ void HuePalette(float correction=1);
+ enum ImageOpType { OpAdd, OpAnd, OpXor, OpOr, OpMask, OpSrcCopy, OpDstCopy, OpSub, OpSrcBlend, OpScreen, OpAvg, OpBlendAlpha };
+ void Mix(CxImage & imgsrc2, ImageOpType op, int32_t lXOffset = 0, int32_t lYOffset = 0, bool bMixAlpha = false);
+ void MixFrom(CxImage & imagesrc2, int32_t lXOffset, int32_t lYOffset);
+ bool UnsharpMask(float radius = 5.0f, float amount = 0.5f, int32_t threshold = 0);
+ bool Lut(uint8_t* pLut);
+ bool Lut(uint8_t* pLutR, uint8_t* pLutG, uint8_t* pLutB, uint8_t* pLutA = 0);
+ bool GaussianBlur(float radius = 1.0f, CxImage* iDst = 0);
+ bool TextBlur(uint8_t threshold = 100, uint8_t decay = 2, uint8_t max_depth = 5, bool bBlurHorizontal = true, bool bBlurVertical = true, CxImage* iDst = 0);
+ bool SelectiveBlur(float radius = 1.0f, uint8_t threshold = 25, CxImage* iDst = 0);
+ bool Solarize(uint8_t level = 128, bool bLinkedChannels = true);
+ bool FloodFill(const int32_t xStart, const int32_t yStart, const RGBQUAD cFillColor, const uint8_t tolerance = 0,
+ uint8_t nOpacity = 255, const bool bSelectFilledArea = false, const uint8_t nSelectionLevel = 255);
+ bool Saturate(const int32_t saturation, const int32_t colorspace = 1);
+ bool ConvertColorSpace(const int32_t dstColorSpace, const int32_t srcColorSpace);
+ int32_t OptimalThreshold(int32_t method = 0, RECT * pBox = 0, CxImage* pContrastMask = 0);
+ bool AdaptiveThreshold(int32_t method = 0, int32_t nBoxSize = 64, CxImage* pContrastMask = 0, int32_t nBias = 0, float fGlobalLocalBalance = 0.5f);
+ bool RedEyeRemove(float strength = 0.8f);
+ bool Trace(RGBQUAD color_target, RGBQUAD color_trace);
+
+//@}
+
+protected:
+/** \addtogroup Protected */ //@{
+ bool IsPowerof2(int32_t x);
+ bool FFT(int32_t dir,int32_t m,double *x,double *y);
+ bool DFT(int32_t dir,int32_t m,double *x1,double *y1,double *x2,double *y2);
+ bool RepairChannel(CxImage *ch, float radius);
+ // <nipper>
+ int32_t gen_convolve_matrix (float radius, float **cmatrix_p);
+ float* gen_lookup_table (float *cmatrix, int32_t cmatrix_length);
+ void blur_line (float *ctable, float *cmatrix, int32_t cmatrix_length, uint8_t* cur_col, uint8_t* dest_col, int32_t y, int32_t bytes);
+ void blur_text (uint8_t threshold, uint8_t decay, uint8_t max_depth, CxImage* iSrc, CxImage* iDst, uint8_t bytes);
+//@}
+
+public:
+/** \addtogroup ColorSpace */ //@{
+ bool SplitRGB(CxImage* r,CxImage* g,CxImage* b);
+ bool SplitYUV(CxImage* y,CxImage* u,CxImage* v);
+ bool SplitHSL(CxImage* h,CxImage* s,CxImage* l);
+ bool SplitYIQ(CxImage* y,CxImage* i,CxImage* q);
+ bool SplitXYZ(CxImage* x,CxImage* y,CxImage* z);
+ bool SplitCMYK(CxImage* c,CxImage* m,CxImage* y,CxImage* k);
+ static RGBQUAD HSLtoRGB(COLORREF cHSLColor);
+ static RGBQUAD RGBtoHSL(RGBQUAD lRGBColor);
+ static RGBQUAD HSLtoRGB(RGBQUAD lHSLColor);
+ static RGBQUAD YUVtoRGB(RGBQUAD lYUVColor);
+ static RGBQUAD RGBtoYUV(RGBQUAD lRGBColor);
+ static RGBQUAD YIQtoRGB(RGBQUAD lYIQColor);
+ static RGBQUAD RGBtoYIQ(RGBQUAD lRGBColor);
+ static RGBQUAD XYZtoRGB(RGBQUAD lXYZColor);
+ static RGBQUAD RGBtoXYZ(RGBQUAD lRGBColor);
+#endif //CXIMAGE_SUPPORT_DSP
+ static RGBQUAD RGBtoRGBQUAD(COLORREF cr);
+ static COLORREF RGBQUADtoRGB (RGBQUAD c);
+//@}
+
+/** \addtogroup Selection */ //@{
+ bool SelectionIsValid();
+#if CXIMAGE_SUPPORT_SELECTION
+ bool SelectionClear(uint8_t level = 0);
+ bool SelectionCreate();
+ bool SelectionDelete();
+ bool SelectionInvert();
+ bool SelectionMirror();
+ bool SelectionFlip();
+ bool SelectionAddRect(RECT r, uint8_t level = 255);
+ bool SelectionAddEllipse(RECT r, uint8_t level = 255);
+ bool SelectionAddPolygon(POINT *points, int32_t npoints, uint8_t level = 255);
+ bool SelectionAddColor(RGBQUAD c, uint8_t level = 255);
+ bool SelectionAddPixel(int32_t x, int32_t y, uint8_t level = 255);
+ bool SelectionCopy(CxImage &from);
+ bool SelectionIsInside(int32_t x, int32_t y);
+ void SelectionGetBox(RECT& r);
+ bool SelectionToHRGN(HRGN& region);
+ bool SelectionSplit(CxImage *dest);
+ uint8_t SelectionGet(const int32_t x,const int32_t y);
+ bool SelectionSet(CxImage &from);
+ void SelectionRebuildBox();
+ uint8_t* SelectionGetPointer(const int32_t x = 0,const int32_t y = 0);
+//@}
+
+protected:
+/** \addtogroup Protected */ //@{
+ bool BlindSelectionIsInside(int32_t x, int32_t y);
+ uint8_t BlindSelectionGet(const int32_t x,const int32_t y);
+ void SelectionSet(const int32_t x,const int32_t y,const uint8_t level);
+
+public:
+
+#endif //CXIMAGE_SUPPORT_SELECTION
+//@}
+
+#if CXIMAGE_SUPPORT_ALPHA
+/** \addtogroup Alpha */ //@{
+ void AlphaClear();
+ bool AlphaCreate();
+ void AlphaDelete();
+ void AlphaInvert();
+ bool AlphaMirror();
+ bool AlphaFlip();
+ bool AlphaCopy(CxImage &from);
+ bool AlphaSplit(CxImage *dest);
+ void AlphaStrip();
+ void AlphaSet(uint8_t level);
+ bool AlphaSet(CxImage &from);
+ void AlphaSet(const int32_t x,const int32_t y,const uint8_t level);
+ uint8_t AlphaGet(const int32_t x,const int32_t y);
+ uint8_t AlphaGetMax() const;
+ void AlphaSetMax(uint8_t nAlphaMax);
+ bool AlphaIsValid();
+ uint8_t* AlphaGetPointer(const int32_t x = 0,const int32_t y = 0);
+ bool AlphaFromTransparency();
+
+ void AlphaPaletteClear();
+ void AlphaPaletteEnable(bool enable=true);
+ bool AlphaPaletteIsEnabled();
+ bool AlphaPaletteIsValid();
+ bool AlphaPaletteSplit(CxImage *dest);
+//@}
+
+protected:
+/** \addtogroup Protected */ //@{
+ uint8_t BlindAlphaGet(const int32_t x,const int32_t y);
+//@}
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+public:
+#if CXIMAGE_SUPPORT_LAYERS
+/** \addtogroup Layers */ //@{
+ bool LayerCreate(int32_t position = -1);
+ bool LayerDelete(int32_t position = -1);
+ void LayerDeleteAll();
+ CxImage* GetLayer(int32_t position);
+ CxImage* GetParent() const;
+ int32_t GetNumLayers() const;
+ int32_t LayerDrawAll(HDC hdc, int32_t x=0, int32_t y=0, int32_t cx = -1, int32_t cy = -1, RECT* pClipRect = 0, bool bSmooth = false);
+ int32_t LayerDrawAll(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false);
+//@}
+#endif //CXIMAGE_SUPPORT_LAYERS
+
+protected:
+/** \addtogroup Protected */ //@{
+ void Startup(uint32_t imagetype = 0);
+ void CopyInfo(const CxImage &src);
+ void Ghost(const CxImage *src);
+ void RGBtoBGR(uint8_t *buffer, int32_t length);
+ static float HueToRGB(float n1,float n2, float hue);
+ void Bitfield2RGB(uint8_t *src, uint32_t redmask, uint32_t greenmask, uint32_t bluemask, uint8_t bpp);
+ static int32_t CompareColors(const void *elem1, const void *elem2);
+ int16_t m_ntohs(const int16_t word);
+ int32_t m_ntohl(const int32_t dword);
+ void bihtoh(BITMAPINFOHEADER* bih);
+
+ void* pDib; //contains the header, the palette, the pixels
+ BITMAPINFOHEADER head; //standard header
+ CXIMAGEINFO info; //extended information
+ uint8_t* pSelection; //selected region
+ uint8_t* pAlpha; //alpha channel
+ CxImage** ppLayers; //generic layers
+ CxImage** ppFrames;
+//@}
+};
+
+////////////////////////////////////////////////////////////////////////////
+#endif // !defined(__CXIMAGE_H)
diff --git a/archive/hge/CxImage/ximagif.cpp b/archive/hge/CxImage/ximagif.cpp new file mode 100644 index 0000000..8c94b9e --- /dev/null +++ b/archive/hge/CxImage/ximagif.cpp @@ -0,0 +1,1681 @@ +/*
+ * File: ximagif.cpp
+ * Purpose: Platform Independent GIF Image Class Loader and Writer
+ * 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximagif.h"
+
+#if CXIMAGE_SUPPORT_GIF
+
+#include "ximaiter.h"
+
+#if defined (_WIN32_WCE)
+ #define assert(s)
+#else
+ #include <assert.h>
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+CxImageGIF::CxImageGIF(): CxImage(CXIMAGE_FORMAT_GIF)
+{
+ buf = new uint8_t [GIFBUFTAM + 1];
+
+ stack = new uint8_t [MAX_CODES + 1];
+ suffix = new uint8_t [MAX_CODES + 1];
+ prefix = new uint16_t [MAX_CODES + 1];
+
+ htab = new int32_t [HSIZE];
+ codetab = new uint16_t [HSIZE];
+
+ byte_buff = new uint8_t [257];
+ accum = new char [256];
+ m_comment = new char [256];
+
+ m_loops=0;
+ info.dispmeth=0;
+ m_comment[0]='\0';
+
+}
+////////////////////////////////////////////////////////////////////////////////
+CxImageGIF::~CxImageGIF()
+{
+ delete [] buf;
+
+ delete [] stack;
+ delete [] suffix;
+ delete [] prefix;
+
+ delete [] htab;
+ delete [] codetab;
+
+ delete [] byte_buff;
+ delete [] accum;
+ delete [] m_comment;
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageGIF::Decode(CxFile *fp)
+{
+ /* AD - for transparency */
+ struct_dscgif dscgif;
+ struct_image image;
+ struct_TabCol TabCol;
+
+ if (fp == NULL) return false;
+
+ fp->Read(&dscgif,/*sizeof(dscgif)*/13,1);
+ //if (strncmp(dscgif.header,"GIF8",3)!=0) {
+ if (strncmp(dscgif.header,"GIF8",4)!=0) return FALSE;
+
+ // Avoid Byte order problem with Mac <AMSN>
+ dscgif.scrheight = m_ntohs(dscgif.scrheight);
+ dscgif.scrwidth = m_ntohs(dscgif.scrwidth);
+
+ if (info.nEscape == -1) {
+ // Return output dimensions only
+ head.biWidth = dscgif.scrwidth;
+ head.biHeight = dscgif.scrheight;
+ info.dwType = CXIMAGE_FORMAT_GIF;
+ return true;
+ }
+
+ /* AD - for interlace */
+ TabCol.sogct = (int16_t)(1 << ((dscgif.pflds & 0x07)+1));
+ TabCol.colres = (int16_t)(((dscgif.pflds & 0x70) >> 4) + 1);
+
+ // assume that the image is a truecolor-gif if
+ // 1) no global color map found
+ // 2) (image.w, image.h) of the 1st image != (dscgif.scrwidth, dscgif.scrheight)
+ int32_t bTrueColor=0;
+ CxImage* imaRGB=NULL;
+
+ // Global colour map?
+ if (dscgif.pflds & 0x80)
+ fp->Read(TabCol.paleta,sizeof(struct rgb_color)*TabCol.sogct,1);
+ else
+ bTrueColor++; //first chance for a truecolor gif
+
+ int32_t first_transparent_index = 0;
+
+ int32_t iImage = 0;
+ info.nNumFrames=get_num_frames(fp,&TabCol,&dscgif);
+
+ if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)) return false;
+
+ //it cannot be a true color GIF with only one frame
+ if (info.nNumFrames == 1)
+ bTrueColor=0;
+
+ char ch;
+ bool bPreviousWasNull = true;
+ int32_t prevdispmeth = 0;
+ CxImage *previousFrame = NULL;
+
+ for (BOOL bContinue = TRUE; bContinue; )
+ {
+ if (fp->Read(&ch, sizeof(ch), 1) != 1) {break;}
+
+ if (info.nEscape > 0) return false; // <vho> - cancel decoding
+ if (bPreviousWasNull || ch==0)
+ {
+ switch (ch)
+ {
+ case '!': // extension
+ {
+ bContinue = DecodeExtension(fp);
+ break;
+ }
+ case ',': // image
+ {
+ assert(sizeof(image) == 9);
+ fp->Read(&image,sizeof(image),1);
+ //avoid byte order problems with Solaris <candan> <AMSN>
+ image.l = m_ntohs(image.l);
+ image.t = m_ntohs(image.t);
+ image.w = m_ntohs(image.w);
+ image.h = m_ntohs(image.h);
+
+ if (((image.l + image.w) > dscgif.scrwidth)||((image.t + image.h) > dscgif.scrheight))
+ break;
+
+ // check if it could be a truecolor gif
+ if ((iImage==0) && (image.w != dscgif.scrwidth) && (image.h != dscgif.scrheight))
+ bTrueColor++;
+
+ rgb_color locpal[256]; //Local Palette
+ rgb_color* pcurpal = TabCol.paleta; //Current Palette
+ int16_t palcount = TabCol.sogct; //Current Palette color count
+
+ // Local colour map?
+ if (image.pf & 0x80) {
+ palcount = (int16_t)(1 << ((image.pf & 0x07) +1));
+ assert(3 == sizeof(struct rgb_color));
+ fp->Read(locpal,sizeof(struct rgb_color)*palcount,1);
+ pcurpal = locpal;
+ }
+
+ int32_t bpp; //<DP> select the correct bit per pixel value
+ if (palcount <= 2) bpp = 1;
+ else if (palcount <= 16) bpp = 4;
+ else bpp = 8;
+
+ CxImageGIF backimage;
+ backimage.CopyInfo(*this);
+ if (iImage==0){
+ //first frame: build image background
+ backimage.Create(dscgif.scrwidth, dscgif.scrheight, bpp, CXIMAGE_FORMAT_GIF);
+ first_transparent_index = info.nBkgndIndex;
+ backimage.Clear((uint8_t)gifgce.transpcolindex);
+ previousFrame = new CxImage(backimage);
+ previousFrame->SetRetreiveAllFrames(false);
+ } else {
+ //generic frame: handle disposal method from previous one
+ /*Values : 0 - No disposal specified. The decoder is
+ not required to take any action.
+ 1 - Do not dispose. The graphic is to be left
+ in place.
+ 2 - Restore to background color. The area used by the
+ graphic must be restored to the background color.
+ 3 - Restore to previous. The decoder is required to
+ restore the area overwritten by the graphic with
+ what was there prior to rendering the graphic.
+ */
+ /* backimage.Copy(*this);
+ if (prevdispmeth==2){
+ backimage.Clear((uint8_t)first_transparent_index);
+ }*/
+ if (prevdispmeth==2){
+ backimage.Copy(*this,false,false,false);
+ backimage.Clear((uint8_t)first_transparent_index);
+ } else if (prevdispmeth==3) {
+ backimage.Copy(*this,false,false,false);
+ backimage.Create(previousFrame->GetWidth(),
+ previousFrame->GetHeight(),
+ previousFrame->GetBpp(),CXIMAGE_FORMAT_GIF);
+ memcpy(backimage.GetDIB(),previousFrame->GetDIB(),
+ backimage.GetSize());
+ //backimage.AlphaSet(*previousFrame);
+ } else {
+ backimage.Copy(*this);
+ }
+ }
+
+ //active frame
+ Create(image.w, image.h, bpp, CXIMAGE_FORMAT_GIF);
+
+ if ((image.pf & 0x80) || (dscgif.pflds & 0x80)) {
+ uint8_t r[256], g[256], b[256];
+ int32_t i;//, has_white = 0;
+
+ for (i=0; i < palcount; i++) {
+ r[i] = pcurpal[i].r;
+ g[i] = pcurpal[i].g;
+ b[i] = pcurpal[i].b;
+ //if (RGB(r[i],g[i],b[i]) == 0xFFFFFF) has_white = 1;
+ }
+
+ // Force transparency colour white...
+ //if (0) if (info.nBkgndIndex >= 0)
+ // r[info.nBkgndIndex] = g[info.nBkgndIndex] = b[info.nBkgndIndex] = 255;
+ // Fill in with white // AD
+ if (info.nBkgndIndex >= 0) {
+ while (i < 256) {
+ //has_white = 1;
+ r[i] = g[i] = b[i] = 255;
+ i++;
+ }
+ }
+
+ // Force last colour to white... // AD
+ //if ((info.nBkgndIndex >= 0) && !has_white) {
+ // r[255] = g[255] = b[255] = 255;
+ //}
+
+ SetPalette((info.nBkgndIndex >= 0 ? 256 : palcount), r, g, b);
+ }
+
+ CImageIterator* iter = new CImageIterator(this);
+ iter->Upset();
+ int32_t badcode=0;
+ ibf = GIFBUFTAM+1;
+
+ interlaced = image.pf & 0x40;
+ iheight = image.h;
+ istep = 8;
+ iypos = 0;
+ ipass = 0;
+
+ int32_t pos_start = fp->Tell();
+ //if (interlaced) log << "Interlaced" << endl;
+ decoder(fp, iter, image.w, badcode);
+ delete iter;
+
+ if (info.nEscape) return false; // <vho> - cancel decoding
+
+ if (bTrueColor<2 ){ //standard GIF: mix frame with background
+ backimage.IncreaseBpp(bpp);
+ backimage.GifMix(*this,image);
+ backimage.SetTransIndex(first_transparent_index);
+ backimage.SetPalette(GetPalette());
+ Transfer(backimage,false);
+ } else { //it's a truecolor gif!
+ //force full image decoding
+ info.nFrame=info.nNumFrames-1;
+ //build the RGB image
+ if (imaRGB==NULL) imaRGB = new CxImage(dscgif.scrwidth,dscgif.scrheight,24,CXIMAGE_FORMAT_GIF);
+ //copy the partial image into the full RGB image
+ for(int32_t y=0;y<image.h;y++){
+ for (int32_t x=0;x<image.w;x++){
+ imaRGB->SetPixelColor(x+image.l,dscgif.scrheight-1-image.t-y,GetPixelColor(x,image.h-y-1));
+ }
+ }
+ }
+
+ prevdispmeth = (gifgce.flags >> 2) & 0x7;
+
+ //restore the correct position in the file for the next image
+ if (badcode){
+ seek_next_image(fp,pos_start);
+ } else {
+ fp->Seek(-(ibfmax - ibf - 1), SEEK_CUR);
+ }
+
+ if (info.bGetAllFrames && imaRGB == NULL) {
+ if (iImage == 0) {
+ DestroyFrames();
+ ppFrames = new CxImage*[info.nNumFrames];
+ for(int32_t frameIdx = 0; frameIdx < info.nNumFrames; frameIdx++){
+ ppFrames[frameIdx] = NULL;
+ }
+ }
+ ppFrames[iImage] = new CxImage(*this);
+ ppFrames[iImage]->SetRetreiveAllFrames(false);
+ }
+ if (prevdispmeth <= 1) {
+ delete previousFrame;
+ previousFrame = new CxImage(*this);
+ previousFrame->SetRetreiveAllFrames(false);
+ }
+
+ if ((info.nFrame==iImage) && (info.bGetAllFrames==false)) bContinue=false; else iImage++;
+
+ break;
+ }
+ case ';': //terminator
+ bContinue=false;
+ break;
+ default:
+ bPreviousWasNull = (ch==0);
+ break;
+ }
+ }
+ }
+
+ if (bTrueColor>=2 && imaRGB){
+ if (gifgce.flags & 0x1){
+ imaRGB->SetTransColor(GetPaletteColor((uint8_t)info.nBkgndIndex));
+ imaRGB->SetTransIndex(0);
+ }
+ Transfer(*imaRGB);
+ }
+ delete imaRGB;
+
+ delete previousFrame;
+
+ return true;
+
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageGIF::DecodeExtension(CxFile *fp)
+{
+ bool bContinue;
+ uint8_t count;
+ uint8_t fc;
+
+ bContinue = (1 == fp->Read(&fc, sizeof(fc), 1));
+ if (bContinue) {
+ /* AD - for transparency */
+ if (fc == 0xF9) {
+ bContinue = (1 == fp->Read(&count, sizeof(count), 1));
+ if (bContinue) {
+ assert(sizeof(gifgce) == 4);
+ bContinue = (count == fp->Read(&gifgce, 1, sizeof(gifgce)));
+ gifgce.delaytime = m_ntohs(gifgce.delaytime); // Avoid Byte order problem with Mac <AMSN>
+ if (bContinue) {
+ info.nBkgndIndex = (gifgce.flags & 0x1) ? gifgce.transpcolindex : -1;
+ info.dwFrameDelay = gifgce.delaytime;
+ SetDisposalMethod((gifgce.flags >> 2) & 0x7);
+ } } }
+
+ if (fc == 0xFE) { //<DP> Comment block
+ bContinue = (1 == fp->Read(&count, sizeof(count), 1));
+ if (bContinue) {
+ bContinue = (1 == fp->Read(m_comment, count, 1));
+ m_comment[count]='\0';
+ } }
+
+ if (fc == 0xFF) { //<DP> Application Extension block
+ bContinue = (1 == fp->Read(&count, sizeof(count), 1));
+ if (bContinue) {
+ bContinue = (count==11);
+ if (bContinue){
+ char AppID[11];
+ bContinue = (1 == fp->Read(AppID, count, 1));
+ if (bContinue) {
+ bContinue = (1 == fp->Read(&count, sizeof(count), 1));
+ if (bContinue) {
+ uint8_t* dati = (uint8_t*)malloc(count);
+ bContinue = (dati!=NULL);
+ if (bContinue){
+ bContinue = (1 == fp->Read(dati, count, 1));
+ if (count>2){
+ m_loops = dati[1]+256*dati[2];
+ }
+ }
+ free(dati);
+ } } } } }
+
+ while (bContinue && fp->Read(&count, sizeof(count), 1) && count) {
+ //log << "Skipping " << count << " bytes" << endl;
+ fp->Seek(count, SEEK_CUR);
+ }
+ }
+ return bContinue;
+
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+
+// - This external (machine specific) function is expected to return
+// either the next uint8_t from the GIF file, or a negative error number.
+int32_t CxImageGIF::get_byte(CxFile* file)
+{
+ if (ibf>=GIFBUFTAM){
+ // FW 06/02/98 >>>
+ ibfmax = (int32_t)file->Read( buf , 1 , GIFBUFTAM) ;
+ if( ibfmax < GIFBUFTAM ) buf[ ibfmax ] = 255 ;
+ // FW 06/02/98 <<<
+ ibf = 0;
+ }
+ if (ibf>=ibfmax) return -1; //<DP> avoid overflows
+ return buf[ibf++];
+}
+////////////////////////////////////////////////////////////////////////////////
+/* - This function takes a full line of pixels (one uint8_t per pixel) and
+ * displays them (or does whatever your program wants with them...). It
+ * should return zero, or negative if an error or some other event occurs
+ * which would require aborting the decode process... Note that the length
+ * passed will almost always be equal to the line length passed to the
+ * decoder function, with the sole exception occurring when an ending code
+ * occurs in an odd place in the GIF file... In any case, linelen will be
+ * equal to the number of pixels passed...
+*/
+int32_t CxImageGIF::out_line(CImageIterator* iter, uint8_t *pixels, int32_t linelen)
+{
+ if (iter == NULL || pixels == NULL)
+ return -1;
+
+ //<DP> for 1 & 4 bpp images, the pixels are compressed
+ if (head.biBitCount < 8){
+ for(int32_t x=0;x<head.biWidth;x++){
+ uint8_t pos;
+ uint8_t* iDst= pixels + (x*head.biBitCount >> 3);
+ if (head.biBitCount==4){
+ pos = (uint8_t)(4*(1-x%2));
+ *iDst &= ~(0x0F<<pos);
+ *iDst |= ((pixels[x] & 0x0F)<<pos);
+ } else if (head.biBitCount==1){
+ pos = (uint8_t)(7-x%8);
+ *iDst &= ~(0x01<<pos);
+ *iDst |= ((pixels[x] & 0x01)<<pos);
+ }
+ }
+ }
+
+ /* AD - for interlace */
+ if (interlaced) {
+ iter->SetY(iheight-iypos-1);
+ iter->SetRow(pixels, linelen);
+
+ if ((iypos += istep) >= iheight) {
+ do {
+ if (ipass++ > 0) istep /= 2;
+ iypos = istep / 2;
+ }
+ while (iypos > iheight);
+ }
+ return 0;
+ } else {
+ if (iter->ItOK()) {
+ iter->SetRow(pixels, linelen);
+ (void)iter->PrevRow();
+ return 0;
+ } else {
+ // puts("chafeo");
+ return -1;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+// SaveFile - writes GIF87a gif file
+// Randy Spann 6/15/97
+// R.Spann@ConnRiver.net
+bool CxImageGIF::Encode(CxFile * fp)
+{
+ if (EncodeSafeCheck(fp)) return false;
+
+ if(head.biBitCount > 8) {
+ //strcpy(info.szLastError,"GIF Images must be 8 bit or less");
+ //return FALSE;
+ return EncodeRGB(fp);
+ }
+
+ if ( GetNumFrames()>1 && ppFrames ) {
+ return Encode(fp, ppFrames, GetNumFrames() );
+ }
+
+ EncodeHeader(fp);
+
+ EncodeExtension(fp);
+
+ EncodeComment(fp);
+
+ EncodeBody(fp);
+
+ fp->PutC(';'); // Write the GIF file terminator
+
+ return true; // done!
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageGIF::Encode(CxFile * fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap, bool bLocalDispMeth)
+{
+ cx_try {
+ if (fp==NULL) cx_throw("invalid file pointer");
+ if (pImages==NULL || pagecount<=0 || pImages[0]==NULL) cx_throw("multipage GIF, no images!");
+
+ int32_t i;
+ for (i=0; i<pagecount; i++){
+ if (pImages[i]==NULL)
+ cx_throw("Bad image pointer");
+ if (!(pImages[i]->IsValid()))
+ cx_throw("Empty image");
+ if (pImages[i]->GetNumColors()==0)
+ cx_throw("CxImageGIF::Encode cannot create animated GIFs with a true color frame. Use DecreaseBpp before");
+ }
+
+ CxImageGIF ghost;
+
+ //write the first image
+ ghost.Ghost(pImages[0]);
+ ghost.EncodeHeader(fp);
+
+ if (m_loops!=1){
+ ghost.SetLoops(max(0,m_loops-1));
+ ghost.EncodeLoopExtension(fp);
+ }
+
+ if (bLocalDispMeth) {
+ ghost.EncodeExtension(fp);
+ } else {
+ uint8_t dm = ghost.GetDisposalMethod();
+ ghost.SetDisposalMethod(GetDisposalMethod());
+ ghost.EncodeExtension(fp);
+ ghost.SetDisposalMethod(dm);
+ }
+
+ EncodeComment(fp);
+
+ ghost.EncodeBody(fp);
+
+ for (i=1; i<pagecount; i++){
+ ghost.Ghost(pImages[i]);
+
+ if (bLocalDispMeth) {
+ ghost.EncodeExtension(fp);
+ } else {
+ uint8_t dm = ghost.GetDisposalMethod();
+ ghost.SetDisposalMethod(GetDisposalMethod());
+ ghost.EncodeExtension(fp);
+ ghost.SetDisposalMethod(dm);
+ }
+
+ ghost.EncodeBody(fp,bLocalColorMap);
+ }
+
+ fp->PutC(';'); // Write the GIF file terminator
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::EncodeHeader(CxFile *fp)
+{
+ fp->Write("GIF89a",1,6); //GIF Header
+
+ Putword(head.biWidth,fp); //Logical screen descriptor
+ Putword(head.biHeight,fp);
+
+ uint8_t Flags;
+ if (head.biClrUsed==0){
+ Flags=0x11;
+ } else {
+ Flags = 0x80;
+ Flags |=(head.biBitCount - 1) << 5;
+ Flags |=(head.biBitCount - 1);
+ }
+
+ fp->PutC(Flags); //GIF "packed fields"
+ fp->PutC(0); //GIF "BackGround"
+ fp->PutC(0); //GIF "pixel aspect ratio"
+
+ if (head.biClrUsed!=0){
+ RGBQUAD* pPal = GetPalette();
+ for(uint32_t i=0; i<head.biClrUsed; ++i)
+ {
+ fp->PutC(pPal[i].rgbRed);
+ fp->PutC(pPal[i].rgbGreen);
+ fp->PutC(pPal[i].rgbBlue);
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::EncodeExtension(CxFile *fp)
+{
+ // TRK BEGIN : transparency
+ fp->PutC('!');
+ fp->PutC(TRANSPARENCY_CODE);
+
+ gifgce.flags = 0;
+ gifgce.flags |= ((info.nBkgndIndex != -1) ? 1 : 0);
+ gifgce.flags |= ((GetDisposalMethod() & 0x7) << 2);
+ gifgce.delaytime = (uint16_t)info.dwFrameDelay;
+ gifgce.transpcolindex = (uint8_t)info.nBkgndIndex;
+
+ //Invert byte order in case we use a byte order arch, then set it back <AMSN>
+ gifgce.delaytime = m_ntohs(gifgce.delaytime);
+ fp->PutC(sizeof(gifgce));
+ fp->Write(&gifgce, sizeof(gifgce), 1);
+ gifgce.delaytime = m_ntohs(gifgce.delaytime);
+
+ fp->PutC(0);
+ // TRK END
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::EncodeLoopExtension(CxFile *fp)
+{
+ fp->PutC('!'); //byte 1 : 33 (hex 0x21) GIF Extension code
+ fp->PutC(255); //byte 2 : 255 (hex 0xFF) Application Extension Label
+ fp->PutC(11); //byte 3 : 11 (hex (0x0B) Length of Application Block (eleven bytes of data to follow)
+ fp->Write("NETSCAPE2.0",11,1);
+ fp->PutC(3); //byte 15 : 3 (hex 0x03) Length of Data Sub-Block (three bytes of data to follow)
+ fp->PutC(1); //byte 16 : 1 (hex 0x01)
+ Putword(m_loops,fp); //bytes 17 to 18 : 0 to 65535, an unsigned integer in lo-hi byte format.
+ //This indicate the number of iterations the loop should be executed.
+ fp->PutC(0); //bytes 19 : 0 (hex 0x00) a Data Sub-block Terminator.
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::EncodeBody(CxFile *fp, bool bLocalColorMap)
+{
+ curx = 0;
+ cury = head.biHeight - 1; //because we read the image bottom to top
+ CountDown = (int32_t)head.biWidth * (int32_t)head.biHeight;
+
+ fp->PutC(',');
+
+ Putword(info.xOffset,fp);
+ Putword(info.yOffset,fp);
+ Putword(head.biWidth,fp);
+ Putword(head.biHeight,fp);
+
+ uint8_t Flags=0x00; //non-interlaced (0x40 = interlaced) (0x80 = LocalColorMap)
+ if (bLocalColorMap) { Flags|=0x80; Flags|=head.biBitCount-1; }
+ fp->PutC(Flags);
+
+ if (bLocalColorMap){
+ Flags|=0x87;
+ RGBQUAD* pPal = GetPalette();
+ for(uint32_t i=0; i<head.biClrUsed; ++i)
+ {
+ fp->PutC(pPal[i].rgbRed);
+ fp->PutC(pPal[i].rgbGreen);
+ fp->PutC(pPal[i].rgbBlue);
+ }
+ }
+
+ int32_t InitCodeSize = head.biBitCount <=1 ? 2 : head.biBitCount;
+ // Write out the initial code size
+ fp->PutC((uint8_t)InitCodeSize);
+
+ // Go and actually compress the data
+ switch (GetCodecOption(CXIMAGE_FORMAT_GIF))
+ {
+ case 1: //uncompressed
+ compressNONE(InitCodeSize+1, fp);
+ break;
+ case 2: //RLE
+ compressRLE(InitCodeSize+1, fp);
+ break;
+ default: //LZW
+ compressLZW(InitCodeSize+1, fp);
+ }
+
+ // Write out a Zero-length packet (to end the series)
+ fp->PutC(0);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::EncodeComment(CxFile *fp)
+{
+ uint32_t n = (uint32_t) strlen(m_comment);
+ if (n>255) n=255;
+ if (n) {
+ fp->PutC('!'); //extension code:
+ fp->PutC(254); //comment extension
+ fp->PutC((uint8_t)n); //size of comment
+ fp->Write(m_comment,n,1);
+ fp->PutC(0); //block terminator
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageGIF::EncodeRGB(CxFile *fp)
+{
+ EncodeHeader(fp);
+
+// EncodeLoopExtension(fp);
+
+ EncodeComment(fp);
+
+ uint32_t w,h;
+ w=h=0;
+ const int32_t cellw = 17;
+ const int32_t cellh = 15;
+ CxImageGIF tmp;
+ for (int32_t y=0;y<head.biHeight;y+=cellh){
+ for (int32_t x=0;x<head.biWidth;x+=cellw){
+ if ((head.biWidth -x)<cellw) w=head.biWidth -x; else w=cellw;
+ if ((head.biHeight-y)<cellh) h=head.biHeight-y; else h=cellh;
+
+ if (w!=tmp.GetWidth() || h!=tmp.GetHeight()) tmp.Create(w,h,8);
+
+ if (IsTransparent()){
+ tmp.SetTransIndex(0);
+ tmp.SetPaletteColor(0,GetTransColor());
+ }
+
+ uint8_t i;
+ for (uint32_t j=0;j<h;j++){
+ for (uint32_t k=0;k<w;k++){
+ i=(uint8_t)(1+k+cellw*j);
+ tmp.SetPaletteColor(i,GetPixelColor(x+k,head.biHeight-y-h+j));
+ tmp.SetPixelIndex(k,j,tmp.GetNearestIndex(tmp.GetPaletteColor(i)));
+ }
+ }
+
+ tmp.SetOffset(x,y);
+ tmp.EncodeExtension(fp);
+ tmp.EncodeBody(fp,true);
+ }
+ }
+
+ fp->PutC(';'); // Write the GIF file terminator
+
+ return true; // done!
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+// Return the next pixel from the image
+// <DP> fix for 1 & 4 bpp images
+int32_t CxImageGIF::GifNextPixel( )
+{
+ if( CountDown == 0 ) return EOF;
+ --CountDown;
+ int32_t r = GetPixelIndex(curx,cury);
+ // Bump the current X position
+ ++curx;
+ if( curx == head.biWidth ){
+ curx = 0;
+ cury--; //bottom to top
+ }
+ return r;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::Putword(int32_t w, CxFile *fp )
+{
+ fp->PutC((uint8_t)(w & 0xff));
+ fp->PutC((uint8_t)((w >> 8) & 0xff));
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::compressNONE( int32_t init_bits, CxFile* outfile)
+{
+ register int32_t c;
+ register int32_t ent;
+
+ // g_init_bits - initial number of bits
+ // g_outfile - pointer to output file
+ g_init_bits = init_bits;
+ g_outfile = outfile;
+
+ // Set up the necessary values
+ cur_accum = cur_bits = clear_flg = 0;
+ maxcode = (int16_t)MAXCODE(n_bits = g_init_bits);
+ code_int maxmaxcode = (code_int)1 << MAXBITSCODES;
+
+ ClearCode = (1 << (init_bits - 1));
+ EOFCode = ClearCode + 1;
+ free_ent = (int16_t)(ClearCode + 2);
+
+ a_count=0;
+ ent = GifNextPixel( );
+
+ output( (code_int)ClearCode );
+
+ while ( ent != EOF ) {
+ c = GifNextPixel();
+
+ output ( (code_int) ent );
+ ent = c;
+ if ( free_ent < maxmaxcode ) {
+ free_ent++;
+ } else {
+ free_ent=(int16_t)(ClearCode+2);
+ clear_flg=1;
+ output((code_int)ClearCode);
+ }
+ }
+ // Put out the final code.
+ output( (code_int) EOFCode );
+}
+////////////////////////////////////////////////////////////////////////////////
+
+/***************************************************************************
+ *
+ * GIFCOMPR.C - LZW GIF Image compression routines
+ *
+ ***************************************************************************/
+
+void CxImageGIF::compressLZW( int32_t init_bits, CxFile* outfile)
+{
+ register int32_t fcode;
+ register int32_t c;
+ register int32_t ent;
+ register int32_t hshift;
+ register int32_t disp;
+ register int32_t i;
+
+ // g_init_bits - initial number of bits
+ // g_outfile - pointer to output file
+ g_init_bits = init_bits;
+ g_outfile = outfile;
+
+ // Set up the necessary values
+ cur_accum = cur_bits = clear_flg = 0;
+ maxcode = (int16_t)MAXCODE(n_bits = g_init_bits);
+ code_int maxmaxcode = (code_int)1 << MAXBITSCODES;
+
+ ClearCode = (1 << (init_bits - 1));
+ EOFCode = ClearCode + 1;
+ free_ent = (int16_t)(ClearCode + 2);
+
+ a_count=0;
+ ent = GifNextPixel( );
+
+ hshift = 0;
+ for ( fcode = (int32_t) HSIZE; fcode < 65536L; fcode *= 2L ) ++hshift;
+ hshift = 8 - hshift; /* set hash code range bound */
+ cl_hash((int32_t)HSIZE); /* clear hash table */
+ output( (code_int)ClearCode );
+
+ while ( (c = GifNextPixel( )) != EOF ) {
+
+ fcode = (int32_t) (((int32_t) c << MAXBITSCODES) + ent);
+ i = (((code_int)c << hshift) ^ ent); /* xor hashing */
+
+ if ( HashTabOf (i) == fcode ) {
+ ent = CodeTabOf (i);
+ continue;
+ } else if ( (int32_t)HashTabOf (i) < 0 ) /* empty slot */
+ goto nomatch;
+ disp = HSIZE - i; /* secondary hash (after G. Knott) */
+ if ( i == 0 ) disp = 1;
+probe:
+ if ( (i -= disp) < 0 ) i += HSIZE;
+ if ( HashTabOf (i) == fcode ) { ent = CodeTabOf (i); continue; }
+ if ( (int32_t)HashTabOf (i) > 0 ) goto probe;
+nomatch:
+ output ( (code_int) ent );
+ ent = c;
+ if ( free_ent < maxmaxcode ) {
+ CodeTabOf (i) = free_ent++; /* code -> hashtable */
+ HashTabOf (i) = fcode;
+ } else {
+ cl_hash((int32_t)HSIZE);
+ free_ent=(int16_t)(ClearCode+2);
+ clear_flg=1;
+ output((code_int)ClearCode);
+ }
+ }
+ // Put out the final code.
+ output( (code_int)ent );
+ output( (code_int) EOFCode );
+}
+////////////////////////////////////////////////////////////////////////////////
+
+static const uint32_t code_mask[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
+ 0x001F, 0x003F, 0x007F, 0x00FF,
+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
+ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
+
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::output( code_int code)
+{
+ cur_accum &= code_mask[ cur_bits ];
+
+ if( cur_bits > 0 )
+ cur_accum |= ((int32_t)code << cur_bits);
+ else
+ cur_accum = code;
+
+ cur_bits += n_bits;
+
+ while( cur_bits >= 8 ) {
+ char_out( (uint32_t)(cur_accum & 0xff) );
+ cur_accum >>= 8;
+ cur_bits -= 8;
+ }
+
+ /*
+ * If the next entry is going to be too big for the code size,
+ * then increase it, if possible.
+ */
+
+ if ( free_ent > maxcode || clear_flg ) {
+ if( clear_flg ) {
+ maxcode = (int16_t)MAXCODE(n_bits = g_init_bits);
+ clear_flg = 0;
+ } else {
+ ++n_bits;
+ if ( n_bits == MAXBITSCODES )
+ maxcode = (code_int)1 << MAXBITSCODES; /* should NEVER generate this code */
+ else
+ maxcode = (int16_t)MAXCODE(n_bits);
+ }
+ }
+
+ if( code == EOFCode ) {
+ // At EOF, write the rest of the buffer.
+ while( cur_bits > 0 ) {
+ char_out( (uint32_t)(cur_accum & 0xff) );
+ cur_accum >>= 8;
+ cur_bits -= 8;
+ }
+
+ flush_char();
+ g_outfile->Flush();
+
+ if(g_outfile->Error()) strcpy(info.szLastError,"Write Error in GIF file");
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+
+void CxImageGIF::cl_hash(int32_t hsize)
+
+{
+ register int32_t *htab_p = htab+hsize;
+
+ register int32_t i;
+ register int32_t m1 = -1L;
+
+ i = hsize - 16;
+
+ do {
+ *(htab_p-16)=m1;
+ *(htab_p-15)=m1;
+ *(htab_p-14)=m1;
+ *(htab_p-13)=m1;
+ *(htab_p-12)=m1;
+ *(htab_p-11)=m1;
+ *(htab_p-10)=m1;
+ *(htab_p-9)=m1;
+ *(htab_p-8)=m1;
+ *(htab_p-7)=m1;
+ *(htab_p-6)=m1;
+ *(htab_p-5)=m1;
+ *(htab_p-4)=m1;
+ *(htab_p-3)=m1;
+ *(htab_p-2)=m1;
+ *(htab_p-1)=m1;
+
+ htab_p-=16;
+ } while ((i-=16) >=0);
+
+ for (i+=16;i>0;--i)
+ *--htab_p=m1;
+}
+
+/*******************************************************************************
+* GIF specific
+*******************************************************************************/
+
+void CxImageGIF::char_out(int32_t c)
+{
+ accum[a_count++]=(char)c;
+ if (a_count >=254)
+ flush_char();
+}
+
+void CxImageGIF::flush_char()
+{
+ if (a_count > 0) {
+ g_outfile->PutC((uint8_t)a_count);
+ g_outfile->Write(accum,1,a_count);
+ a_count=0;
+ }
+}
+
+/*******************************************************************************
+* GIF decoder
+*******************************************************************************/
+/* DECODE.C - An LZW decoder for GIF
+ * Copyright (C) 1987, by Steven A. Bennett
+ * Copyright (C) 1994, C++ version by Alejandro Aguilar Sierra
+*
+ * Permission is given by the author to freely redistribute and include
+ * this code in any program as int32_t as this credit is given where due.
+ *
+ * In accordance with the above, I want to credit Steve Wilhite who wrote
+ * the code which this is heavily inspired by...
+ *
+ * GIF and 'Graphics Interchange Format' are trademarks (tm) of
+ * Compuserve, Incorporated, an H&R Block Company.
+ *
+ * Release Notes: This file contains a decoder routine for GIF images
+ * which is similar, structurally, to the original routine by Steve Wilhite.
+ * It is, however, somewhat noticably faster in most cases.
+ *
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+
+int16_t CxImageGIF::init_exp(int16_t size)
+{
+ curr_size = (int16_t)(size + 1);
+ top_slot = (int16_t)(1 << curr_size);
+ clear = (int16_t)(1 << size);
+ ending = (int16_t)(clear + 1);
+ slot = newcodes = (int16_t)(ending + 1);
+ navail_bytes = nbits_left = 0;
+
+ memset(stack,0,MAX_CODES + 1);
+ memset(prefix,0,MAX_CODES + 1);
+ memset(suffix,0,MAX_CODES + 1);
+ return(0);
+}
+////////////////////////////////////////////////////////////////////////////////
+
+/* get_next_code()
+ * - gets the next code from the GIF file. Returns the code, or else
+ * a negative number in case of file errors...
+ */
+int16_t CxImageGIF::get_next_code(CxFile* file)
+{
+ int16_t i, x;
+ uint32_t ret;
+
+ if (nbits_left == 0) {
+ if (navail_bytes <= 0) {
+ /* Out of bytes in current block, so read next block */
+ pbytes = byte_buff;
+ if ((navail_bytes = (int16_t)get_byte(file)) < 0)
+ return(navail_bytes);
+ else if (navail_bytes) {
+ for (i = 0; i < navail_bytes; ++i) {
+ if ((x = (int16_t)get_byte(file)) < 0) return(x);
+ byte_buff[i] = (uint8_t)x;
+ }
+ }
+ }
+ b1 = *pbytes++;
+ nbits_left = 8;
+ --navail_bytes;
+ }
+
+ if (navail_bytes<0) return ending; // prevent deadlocks (thanks to Mike Melnikov)
+
+ ret = b1 >> (8 - nbits_left);
+ while (curr_size > nbits_left){
+ if (navail_bytes <= 0){
+ /* Out of bytes in current block, so read next block*/
+ pbytes = byte_buff;
+ if ((navail_bytes = (int16_t)get_byte(file)) < 0)
+ return(navail_bytes);
+ else if (navail_bytes){
+ for (i = 0; i < navail_bytes; ++i){
+ if ((x = (int16_t)get_byte(file)) < 0) return(x);
+ byte_buff[i] = (uint8_t)x;
+ }
+ }
+ }
+ b1 = *pbytes++;
+ ret |= b1 << nbits_left;
+ nbits_left += 8;
+ --navail_bytes;
+ }
+ nbits_left = (int16_t)(nbits_left-curr_size);
+ ret &= code_mask[curr_size];
+ return((int16_t)(ret));
+}
+////////////////////////////////////////////////////////////////////////////////
+
+/* int16_t decoder(linewidth)
+ * int16_t linewidth; * Pixels per line of image *
+ *
+ * - This function decodes an LZW image, according to the method used
+ * in the GIF spec. Every *linewidth* "characters" (ie. pixels) decoded
+ * will generate a call to out_line(), which is a user specific function
+ * to display a line of pixels. The function gets it's codes from
+ * get_next_code() which is responsible for reading blocks of data and
+ * seperating them into the proper size codes. Finally, get_byte() is
+ * the global routine to read the next uint8_t from the GIF file.
+ *
+ * It is generally a good idea to have linewidth correspond to the actual
+ * width of a line (as specified in the Image header) to make your own
+ * code a bit simpler, but it isn't absolutely necessary.
+ *
+ * Returns: 0 if successful, else negative. (See ERRS.H)
+ *
+ */
+/* bad_code_count is incremented each time an out of range code is read.
+ * When this value is non-zero after a decode, your GIF file is probably
+ * corrupt in some way...
+ */
+int16_t CxImageGIF::decoder(CxFile* file, CImageIterator* iter, int16_t linewidth, int32_t &bad_code_count)
+{
+ register uint8_t *sp, *bufptr;
+ uint8_t *buf;
+ register int16_t code, fc, oc, bufcnt;
+ int16_t c, size, ret;
+
+ if (linewidth<=0)
+ return BAD_LINE_WIDTH;
+
+ /* Initialize for decoding a new image... */
+ bad_code_count = 0;
+ if ((size = (int16_t)get_byte(file)) < 0) return(size);
+ if (size < 2 || 9 < size) return(BAD_CODE_SIZE);
+ // out_line = outline;
+ init_exp(size);
+ //printf("L %d %x\n",linewidth,size);
+
+ /* Initialize in case they forgot to put in a clear code.
+ * (This shouldn't happen, but we'll try and decode it anyway...)
+ */
+ oc = fc = 0;
+
+ /* Allocate space for the decode buffer */
+ if ((buf = new uint8_t[linewidth + 1]) == NULL) return(OUT_OF_MEMORY);
+
+ /* Set up the stack pointer and decode buffer pointer */
+ sp = stack;
+ bufptr = buf;
+ bufcnt = linewidth;
+
+ /* This is the main loop. For each code we get we pass through the
+ * linked list of prefix codes, pushing the corresponding "character" for
+ * each code onto the stack. When the list reaches a single "character"
+ * we push that on the stack too, and then start unstacking each
+ * character for output in the correct order. Special handling is
+ * included for the clear code, and the whole thing ends when we get
+ * an ending code.
+ */
+ while ((c = get_next_code(file)) != ending) {
+ /* If we had a file error, return without completing the decode*/
+ if (c < 0){
+ delete [] buf;
+ return(0);
+ }
+ /* If the code is a clear code, reinitialize all necessary items.*/
+ if (c == clear){
+ curr_size = (int16_t)(size + 1);
+ slot = newcodes;
+ top_slot = (int16_t)(1 << curr_size);
+
+ /* Continue reading codes until we get a non-clear code
+ * (Another unlikely, but possible case...)
+ */
+ while ((c = get_next_code(file)) == clear);
+
+ /* If we get an ending code immediately after a clear code
+ * (Yet another unlikely case), then break out of the loop.
+ */
+ if (c == ending) break;
+
+ /* Finally, if the code is beyond the range of already set codes,
+ * (This one had better NOT happen... I have no idea what will
+ * result from this, but I doubt it will look good...) then set it
+ * to color zero.
+ */
+ if (c >= slot) c = 0;
+ oc = fc = c;
+
+ /* And let us not forget to put the char into the buffer... And
+ * if, on the off chance, we were exactly one pixel from the end
+ * of the line, we have to send the buffer to the out_line()
+ * routine...
+ */
+ *bufptr++ = (uint8_t)c;
+ if (--bufcnt == 0) {
+ if (iter) {
+ if ((ret = (int16_t)out_line(iter, buf, linewidth)) < 0) {
+ delete [] buf;
+ return(ret);
+ }
+ }
+ bufptr = buf;
+ bufcnt = linewidth;
+ }
+ } else {
+ /* In this case, it's not a clear code or an ending code, so
+ * it must be a code code... So we can now decode the code into
+ * a stack of character codes. (Clear as mud, right?)
+ */
+ code = c;
+
+ /* Here we go again with one of those off chances... If, on the
+ * off chance, the code we got is beyond the range of those already
+ * set up (Another thing which had better NOT happen...) we trick
+ * the decoder into thinking it actually got the last code read.
+ * (Hmmn... I'm not sure why this works... But it does...)
+ */
+ if (code >= slot && sp<(stack+MAX_CODES-1)) {
+ if (code > slot)
+ ++bad_code_count;
+ code = oc;
+ *sp++ = (uint8_t)fc;
+ }
+
+ /* Here we scan back along the linked list of prefixes, pushing
+ * helpless characters (ie. suffixes) onto the stack as we do so.
+ */
+ while (code >= newcodes && sp<(stack+MAX_CODES-1)) {
+ *sp++ = suffix[code];
+ code = prefix[code];
+ }
+
+ /* Push the last character on the stack, and set up the new
+ * prefix and suffix, and if the required slot number is greater
+ * than that allowed by the current bit size, increase the bit
+ * size. (NOTE - If we are all full, we *don't* save the new
+ * suffix and prefix... I'm not certain if this is correct...
+ * it might be more proper to overwrite the last code...
+ */
+ *sp++ = (uint8_t)code;
+ if (slot < top_slot){
+ suffix[slot] = (uint8_t)(fc = (uint8_t)code);
+ prefix[slot++] = oc;
+ oc = c;
+ }
+ if (slot >= top_slot){
+ if (curr_size < 12) {
+ top_slot <<= 1;
+ ++curr_size;
+ }
+ }
+
+ /* Now that we've pushed the decoded string (in reverse order)
+ * onto the stack, lets pop it off and put it into our decode
+ * buffer... And when the decode buffer is full, write another
+ * line...
+ */
+ while (sp > stack) {
+ *bufptr++ = *(--sp);
+ if (--bufcnt == 0) {
+ if (iter) {
+ if ((ret = (int16_t)out_line(iter, buf, linewidth)) < 0) {
+ delete [] buf;
+ return(ret);
+ }
+ }
+ bufptr = buf;
+ bufcnt = linewidth;
+ }
+ }
+ }
+ }
+ ret = 0;
+ if (bufcnt != linewidth && iter)
+ ret = (int16_t)out_line(iter, buf, (linewidth - bufcnt));
+ delete [] buf;
+ return(ret);
+}
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImageGIF::get_num_frames(CxFile *fp,struct_TabCol* TabColSrc,struct_dscgif* dscgif)
+{
+ struct_image image;
+
+ int32_t pos=fp->Tell();
+ int32_t nframes=0;
+
+ struct_TabCol TempTabCol;
+ memcpy(&TempTabCol,TabColSrc,sizeof(struct_TabCol));
+
+ char ch;
+ bool bPreviousWasNull = true;
+
+ for (BOOL bContinue = TRUE; bContinue; )
+ {
+ if (fp->Read(&ch, sizeof(ch), 1) != 1) {break;}
+
+ if (bPreviousWasNull || ch==0)
+ {
+ switch (ch)
+ {
+ case '!': // extension
+ {
+ DecodeExtension(fp);
+ break;
+ }
+ case ',': // image
+ {
+
+ assert(sizeof(image) == 9);
+ //log << "Image header" << endl;
+ fp->Read(&image,sizeof(image),1);
+
+ //avoid byte order problems with Solaris <candan> <AMSN>
+ image.l = m_ntohs(image.l);
+ image.t = m_ntohs(image.t);
+ image.w = m_ntohs(image.w);
+ image.h = m_ntohs(image.h);
+
+ // in case of images with empty screen descriptor, give a last chance
+ if (dscgif->scrwidth==0 && dscgif->scrheight==0){
+ dscgif->scrwidth = image.w;
+ dscgif->scrheight = image.h;
+ }
+
+ if (((image.l + image.w) > dscgif->scrwidth)||((image.t + image.h) > dscgif->scrheight))
+ break;
+
+ nframes++;
+
+ // Local colour map?
+ if (image.pf & 0x80) {
+ TempTabCol.sogct = (int16_t)(1 << ((image.pf & 0x07) +1));
+ assert(3 == sizeof(struct rgb_color));
+ fp->Read(TempTabCol.paleta,sizeof(struct rgb_color)*TempTabCol.sogct,1);
+ //log << "Local colour map" << endl;
+ }
+
+ int32_t badcode=0;
+ ibf = GIFBUFTAM+1;
+
+ interlaced = image.pf & 0x40;
+ iheight = image.h;
+ istep = 8;
+ iypos = 0;
+ ipass = 0;
+
+ int32_t pos_start = fp->Tell();
+
+ //if (interlaced) log << "Interlaced" << endl;
+ decoder(fp, 0, image.w, badcode);
+
+ if (badcode){
+ seek_next_image(fp,pos_start);
+ } else {
+ fp->Seek(-(ibfmax - ibf - 1), SEEK_CUR);
+ }
+
+ break;
+ }
+ case ';': //terminator
+ bContinue=false;
+ break;
+ default:
+ bPreviousWasNull = (ch==0);
+ break;
+ }
+ }
+ }
+
+ fp->Seek(pos,SEEK_SET);
+ return nframes;
+}
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImageGIF::seek_next_image(CxFile* fp, int32_t position)
+{
+ fp->Seek(position, SEEK_SET);
+ char ch1,ch2;
+ ch1=ch2=0;
+ while(fp->Read(&ch2,sizeof(char),1)>0){
+ if (ch1 == 0 && ch2 == ','){
+ fp->Seek(-1,SEEK_CUR);
+ return fp->Tell();
+ } else {
+ ch1 = ch2;
+ }
+ }
+ return -1;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::SetLoops(int32_t loops)
+{ m_loops=loops; }
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImageGIF::GetLoops()
+{ return m_loops; }
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::SetComment(const char* sz_comment_in)
+{ if (sz_comment_in) strncpy(m_comment,sz_comment_in,255); }
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::GetComment(char* sz_comment_out)
+{ if (sz_comment_out) strncpy(sz_comment_out,m_comment,255); }
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::GifMix(CxImage & imgsrc2, struct_image & imgdesc)
+{
+ int32_t ymin = max(0,(int32_t)(GetHeight()-imgdesc.t - imgdesc.h));
+ int32_t ymax = GetHeight()-imgdesc.t;
+ int32_t xmin = imgdesc.l;
+ int32_t xmax = min(GetWidth(), (uint32_t)(imgdesc.l + imgdesc.w));
+
+ int32_t ibg2= imgsrc2.GetTransIndex();
+ uint8_t i2;
+
+ for(int32_t y = ymin; y < ymax; y++){
+ for(int32_t x = xmin; x < xmax; x++){
+ i2 = imgsrc2.GetPixelIndex(x-xmin,y-ymin);
+ if(i2!=ibg2) SetPixelIndex(x,y,i2);
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/*-----------------------------------------------------------------------
+ *
+ * miGIF Compression - mouse and ivo's GIF-compatible compression
+ *
+ * -run length encoding compression routines-
+ *
+ * Copyright (C) 1998 Hutchison Avenue Software Corporation
+ * http://www.hasc.com
+ * info@hasc.com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation. This software is provided "AS IS." The Hutchison Avenue
+ * Software Corporation disclaims all warranties, either express or implied,
+ * including but not limited to implied warranties of merchantability and
+ * fitness for a particular purpose, with respect to this code and accompanying
+ * documentation.
+ *
+ * The miGIF compression routines do not, strictly speaking, generate files
+ * conforming to the GIF spec, since the image data is not LZW-compressed
+ * (this is the point: in order to avoid transgression of the Unisys patent
+ * on the LZW algorithm.) However, miGIF generates data streams that any
+ * reasonably sane LZW decompresser will decompress to what we want.
+ *
+ * miGIF compression uses run length encoding. It compresses horizontal runs
+ * of pixels of the same color. This type of compression gives good results
+ * on images with many runs, for example images with lines, text and solid
+ * shapes on a solid-colored background. It gives little or no compression
+ * on images with few runs, for example digital or scanned photos.
+ *
+ * der Mouse
+ * mouse@rodents.montreal.qc.ca
+ * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
+ *
+ * ivo@hasc.com
+ *
+ * The Graphics Interchange Format(c) is the Copyright property of
+ * CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ * CompuServe Incorporated.
+ *
+ */
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_clear(struct_RLE* rle)
+{
+ rle->out_bits = rle->out_bits_init;
+ rle->out_bump = rle->out_bump_init;
+ rle->out_clear = rle->out_clear_init;
+ rle->out_count = 0;
+ rle->rl_table_max = 0;
+ rle->just_cleared = 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_flush(struct_RLE* rle)
+{
+ if (rle->rl_count == 1){
+ rle_output_plain(rle->rl_pixel,rle);
+ rle->rl_count = 0;
+ return;
+ }
+ if (rle->just_cleared){
+ rle_flush_fromclear(rle->rl_count,rle);
+ } else if ((rle->rl_table_max < 2) || (rle->rl_table_pixel != rle->rl_pixel)) {
+ rle_flush_clearorrep(rle->rl_count,rle);
+ } else {
+ rle_flush_withtable(rle->rl_count,rle);
+ }
+ rle->rl_count = 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_output_plain(int32_t c,struct_RLE* rle)
+{
+ rle->just_cleared = 0;
+ rle_output(c,rle);
+ rle->out_count++;
+ if (rle->out_count >= rle->out_bump){
+ rle->out_bits ++;
+ rle->out_bump += 1 << (rle->out_bits - 1);
+ }
+ if (rle->out_count >= rle->out_clear){
+ rle_output(rle->code_clear,rle);
+ rle_clear(rle);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_flush_fromclear(int32_t count,struct_RLE* rle)
+{
+ int32_t n;
+
+ rle->out_clear = rle->max_ocodes;
+ rle->rl_table_pixel = rle->rl_pixel;
+ n = 1;
+ while (count > 0){
+ if (n == 1){
+ rle->rl_table_max = 1;
+ rle_output_plain(rle->rl_pixel,rle);
+ count --;
+ } else if (count >= n){
+ rle->rl_table_max = n;
+ rle_output_plain(rle->rl_basecode+n-2,rle);
+ count -= n;
+ } else if (count == 1){
+ rle->rl_table_max ++;
+ rle_output_plain(rle->rl_pixel,rle);
+ count = 0;
+ } else {
+ rle->rl_table_max ++;
+ rle_output_plain(rle->rl_basecode+count-2,rle);
+ count = 0;
+ }
+ if (rle->out_count == 0) n = 1; else n ++;
+ }
+ rle_reset_out_clear(rle);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_reset_out_clear(struct_RLE* rle)
+{
+ rle->out_clear = rle->out_clear_init;
+ if (rle->out_count >= rle->out_clear){
+ rle_output(rle->code_clear,rle);
+ rle_clear(rle);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_flush_withtable(int32_t count, struct_RLE* rle)
+{
+ int32_t repmax;
+ int32_t repleft;
+ int32_t leftover;
+
+ repmax = count / rle->rl_table_max;
+ leftover = count % rle->rl_table_max;
+ repleft = (leftover ? 1 : 0);
+ if (rle->out_count+repmax+repleft > rle->max_ocodes){
+ repmax = rle->max_ocodes - rle->out_count;
+ leftover = count - (repmax * rle->rl_table_max);
+ repleft = 1 + rle_compute_triangle_count(leftover,rle->max_ocodes);
+ }
+ if (1+rle_compute_triangle_count(count,rle->max_ocodes) < (uint32_t)(repmax+repleft)){
+ rle_output(rle->code_clear,rle);
+ rle_clear(rle);
+ rle_flush_fromclear(count,rle);
+ return;
+ }
+ rle->out_clear = rle->max_ocodes;
+ for (;repmax>0;repmax--) rle_output_plain(rle->rl_basecode+rle->rl_table_max-2,rle);
+ if (leftover){
+ if (rle->just_cleared){
+ rle_flush_fromclear(leftover,rle);
+ } else if (leftover == 1){
+ rle_output_plain(rle->rl_pixel,rle);
+ } else {
+ rle_output_plain(rle->rl_basecode+leftover-2,rle);
+ }
+ }
+ rle_reset_out_clear(rle);
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImageGIF::rle_compute_triangle_count(uint32_t count, uint32_t nrepcodes)
+{
+ uint32_t perrep;
+ uint32_t cost;
+
+ cost = 0;
+ perrep = (nrepcodes * (nrepcodes+1)) / 2;
+ while (count >= perrep){
+ cost += nrepcodes;
+ count -= perrep;
+ }
+ if (count > 0){
+ uint32_t n;
+ n = rle_isqrt(count);
+ while ((n*(n+1)) >= 2*count) n --;
+ while ((n*(n+1)) < 2*count) n ++;
+ cost += n;
+ }
+ return(cost);
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImageGIF::rle_isqrt(uint32_t x)
+{
+ uint32_t r;
+ uint32_t v;
+
+ if (x < 2) return(x);
+ for (v=x,r=1;v;v>>=2,r<<=1) ;
+ for( ;; )
+ {
+ v = ((x / r) + r) / 2;
+ if ((v == r) || (v == r+1)) return(r);
+ r = v;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_flush_clearorrep(int32_t count, struct_RLE* rle)
+{
+ int32_t withclr;
+ withclr = 1 + rle_compute_triangle_count(count,rle->max_ocodes);
+ if (withclr < count) {
+ rle_output(rle->code_clear,rle);
+ rle_clear(rle);
+ rle_flush_fromclear(count,rle);
+ } else {
+ for (;count>0;count--) rle_output_plain(rle->rl_pixel,rle);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_write_block(struct_RLE* rle)
+{
+ g_outfile->PutC((uint8_t)rle->oblen);
+ g_outfile->Write(rle->oblock,1,rle->oblen);
+ rle->oblen = 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_block_out(uint8_t c, struct_RLE* rle)
+{
+ rle->oblock[rle->oblen++] = c;
+ if (rle->oblen >= 255) rle_write_block(rle);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_block_flush(struct_RLE* rle)
+{
+ if (rle->oblen > 0) rle_write_block(rle);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_output(int32_t val, struct_RLE* rle)
+{
+ rle->obuf |= val << rle->obits;
+ rle->obits += rle->out_bits;
+ while (rle->obits >= 8){
+ rle_block_out((uint8_t)(rle->obuf&0xff),rle);
+ rle->obuf >>= 8;
+ rle->obits -= 8;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::rle_output_flush(struct_RLE* rle)
+{
+ if (rle->obits > 0) rle_block_out((uint8_t)(rle->obuf),rle);
+ rle_block_flush(rle);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageGIF::compressRLE( int32_t init_bits, CxFile* outfile)
+{
+ g_init_bits = init_bits;
+ g_outfile = outfile;
+
+ struct_RLE rle;
+ rle.code_clear = 1 << (init_bits - 1);
+ rle.code_eof = rle.code_clear + 1;
+ rle.rl_basecode = rle.code_eof + 1;
+ rle.out_bump_init = (1 << (init_bits - 1)) - 1;
+ rle.out_clear_init = (init_bits <= 3) ? 9 : (rle.out_bump_init-1);
+ rle.out_bits_init = init_bits;
+ rle.max_ocodes = (1 << MAXBITSCODES) - ((1 << (rle.out_bits_init - 1)) + 3);
+ rle.rl_count = 0;
+ rle_clear(&rle);
+ rle.obuf = 0;
+ rle.obits = 0;
+ rle.oblen = 0;
+
+ rle_output(rle.code_clear,&rle);
+
+ int32_t c;
+ for( ;; )
+ {
+ c = GifNextPixel();
+ if ((rle.rl_count > 0) && (c != rle.rl_pixel)) rle_flush(&rle);
+ if (c == EOF) break;
+ if (rle.rl_pixel == c){
+ rle.rl_count++;
+ } else {
+ rle.rl_pixel = c;
+ rle.rl_count = 1;
+ }
+ }
+ rle_output(rle.code_eof,&rle);
+ rle_output_flush(&rle);
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_GIF
diff --git a/archive/hge/CxImage/ximagif.h b/archive/hge/CxImage/ximagif.h new file mode 100644 index 0000000..4eec35e --- /dev/null +++ b/archive/hge/CxImage/ximagif.h @@ -0,0 +1,244 @@ +/*
+ * File: ximagif.h
+ * Purpose: GIF Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageGIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
+ *
+ * original CImageGIF and CImageIterator implementation are:
+ * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
+ *
+ * 6/15/97 Randy Spann: Added GIF87a writing support
+ * R.Spann@ConnRiver.net
+ *
+ * DECODE.C - An LZW decoder for GIF
+ * Copyright (C) 1987, by Steven A. Bennett
+ * Copyright (C) 1994, C++ version by Alejandro Aguilar Sierra
+ *
+ * In accordance with the above, I want to credit Steve Wilhite who wrote
+ * the code which this is heavily inspired by...
+ *
+ * GIF and 'Graphics Interchange Format' are trademarks (tm) of
+ * Compuserve, Incorporated, an H&R Block Company.
+ *
+ * Release Notes: This file contains a decoder routine for GIF images
+ * which is similar, structurally, to the original routine by Steve Wilhite.
+ * It is, however, somewhat noticably faster in most cases.
+ *
+ * ==========================================================
+ */
+
+#if !defined(__ximaGIF_h)
+#define __ximaGIF_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_GIF
+
+typedef int16_t code_int;
+
+/* Various error codes used by decoder */
+#define OUT_OF_MEMORY -10
+#define BAD_CODE_SIZE -20
+#define READ_ERROR -1
+#define WRITE_ERROR -2
+#define OPEN_ERROR -3
+#define CREATE_ERROR -4
+#define BAD_LINE_WIDTH -5
+#define MAX_CODES 4095
+#define GIFBUFTAM 16383
+#define TRANSPARENCY_CODE 0xF9
+
+//LZW GIF Image compression
+#define MAXBITSCODES 12
+#define HSIZE 5003 /* 80% occupancy */
+#define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
+#define HashTabOf(i) htab[i]
+#define CodeTabOf(i) codetab[i]
+
+
+class CImageIterator;
+class DLL_EXP CxImageGIF: public CxImage
+{
+#pragma pack(1)
+
+typedef struct tag_gifgce{
+ uint8_t flags; /*res:3|dispmeth:3|userinputflag:1|transpcolflag:1*/
+ uint16_t delaytime;
+ uint8_t transpcolindex;
+} struct_gifgce;
+
+typedef struct tag_dscgif{ /* Logic Screen Descriptor */
+ char header[6]; /* Firma and version */
+ uint16_t scrwidth;
+ uint16_t scrheight;
+ char pflds;
+ char bcindx;
+ char pxasrat;
+} struct_dscgif;
+
+typedef struct tag_image{ /* Image Descriptor */
+ uint16_t l;
+ uint16_t t;
+ uint16_t w;
+ uint16_t h;
+ uint8_t pf;
+} struct_image;
+
+typedef struct tag_TabCol{ /* Tabla de colores */
+ int16_t colres; /* color resolution */
+ int16_t sogct; /* size of global color table */
+ rgb_color paleta[256]; /* paleta */
+} struct_TabCol;
+
+typedef struct tag_RLE{
+ int32_t rl_pixel;
+ int32_t rl_basecode;
+ int32_t rl_count;
+ int32_t rl_table_pixel;
+ int32_t rl_table_max;
+ int32_t just_cleared;
+ int32_t out_bits;
+ int32_t out_bits_init;
+ int32_t out_count;
+ int32_t out_bump;
+ int32_t out_bump_init;
+ int32_t out_clear;
+ int32_t out_clear_init;
+ int32_t max_ocodes;
+ int32_t code_clear;
+ int32_t code_eof;
+ uint32_t obuf;
+ int32_t obits;
+ uint8_t oblock[256];
+ int32_t oblen;
+} struct_RLE;
+#pragma pack()
+
+public:
+ CxImageGIF();
+ ~CxImageGIF();
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_GIF);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_GIF);}
+
+ bool Decode(CxFile * fp);
+ bool Decode(FILE *fp) { CxIOFile file(fp); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * fp);
+ bool Encode(CxFile * fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap = false, bool bLocalDispMeth = false);
+ bool Encode(FILE *fp) { CxIOFile file(fp); return Encode(&file); }
+ bool Encode(FILE *fp, CxImage ** pImages, int32_t pagecount, bool bLocalColorMap = false)
+ { CxIOFile file(fp); return Encode(&file, pImages, pagecount, bLocalColorMap); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+ void SetLoops(int32_t loops);
+ int32_t GetLoops();
+ void SetComment(const char* sz_comment_in);
+ void GetComment(char* sz_comment_out);
+
+protected:
+ bool DecodeExtension(CxFile *fp);
+ void EncodeHeader(CxFile *fp);
+ void EncodeLoopExtension(CxFile *fp);
+ void EncodeExtension(CxFile *fp);
+ void EncodeBody(CxFile *fp, bool bLocalColorMap = false);
+ void EncodeComment(CxFile *fp);
+ bool EncodeRGB(CxFile *fp);
+ void GifMix(CxImage & imgsrc2, struct_image & imgdesc);
+
+ struct_gifgce gifgce;
+
+ int32_t curx, cury;
+ int32_t CountDown;
+ uint32_t cur_accum;
+ int32_t cur_bits;
+ int32_t interlaced, iypos, istep, iheight, ipass;
+ int32_t ibf;
+ int32_t ibfmax;
+ uint8_t * buf;
+// Implementation
+ int32_t GifNextPixel ();
+ void Putword (int32_t w, CxFile* fp );
+ void compressNONE (int32_t init_bits, CxFile* outfile);
+ void compressLZW (int32_t init_bits, CxFile* outfile);
+ void output (code_int code );
+ void cl_hash (int32_t hsize);
+ void char_out (int32_t c);
+ void flush_char ();
+ int16_t init_exp(int16_t size);
+ int16_t get_next_code(CxFile*);
+ int16_t decoder(CxFile*, CImageIterator* iter, int16_t linewidth, int32_t &bad_code_count);
+ int32_t get_byte(CxFile*);
+ int32_t out_line(CImageIterator* iter, uint8_t *pixels, int32_t linelen);
+ int32_t get_num_frames(CxFile *f,struct_TabCol* TabColSrc,struct_dscgif* dscgif);
+ int32_t seek_next_image(CxFile* fp, int32_t position);
+
+ int16_t curr_size; /* The current code size */
+ int16_t clear; /* Value for a clear code */
+ int16_t ending; /* Value for a ending code */
+ int16_t newcodes; /* First available code */
+ int16_t top_slot; /* Highest code for current size */
+ int16_t slot; /* Last read code */
+
+ /* The following static variables are used
+ * for seperating out codes */
+ int16_t navail_bytes; /* # bytes left in block */
+ int16_t nbits_left; /* # bits left in current uint8_t */
+ uint8_t b1; /* Current uint8_t */
+ uint8_t * byte_buff; /* Current block */
+ uint8_t *pbytes; /* Pointer to next uint8_t in block */
+ /* The reason we have these seperated like this instead of using
+ * a structure like the original Wilhite code did, is because this
+ * stuff generally produces significantly faster code when compiled...
+ * This code is full of similar speedups... (For a good book on writing
+ * C for speed or for space optomisation, see Efficient C by Tom Plum,
+ * published by Plum-Hall Associates...)
+ */
+ uint8_t * stack; /* Stack for storing pixels */
+ uint8_t * suffix; /* Suffix table */
+ uint16_t * prefix; /* Prefix linked list */
+
+//LZW GIF Image compression routines
+ int32_t * htab;
+ uint16_t * codetab;
+ int32_t n_bits; /* number of bits/code */
+ code_int maxcode; /* maximum code, given n_bits */
+ code_int free_ent; /* first unused entry */
+ int32_t clear_flg;
+ int32_t g_init_bits;
+ CxFile* g_outfile;
+ int32_t ClearCode;
+ int32_t EOFCode;
+
+ int32_t a_count;
+ char * accum;
+
+ char * m_comment;
+ int32_t m_loops;
+
+//RLE compression routines
+ void compressRLE( int32_t init_bits, CxFile* outfile);
+ void rle_clear(struct_RLE* rle);
+ void rle_flush(struct_RLE* rle);
+ void rle_flush_withtable(int32_t count, struct_RLE* rle);
+ void rle_flush_clearorrep(int32_t count, struct_RLE* rle);
+ void rle_flush_fromclear(int32_t count,struct_RLE* rle);
+ void rle_output_plain(int32_t c,struct_RLE* rle);
+ void rle_reset_out_clear(struct_RLE* rle);
+ uint32_t rle_compute_triangle_count(uint32_t count, uint32_t nrepcodes);
+ uint32_t rle_isqrt(uint32_t x);
+ void rle_write_block(struct_RLE* rle);
+ void rle_block_out(uint8_t c, struct_RLE* rle);
+ void rle_block_flush(struct_RLE* rle);
+ void rle_output(int32_t val, struct_RLE* rle);
+ void rle_output_flush(struct_RLE* rle);
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximahist.cpp b/archive/hge/CxImage/ximahist.cpp new file mode 100644 index 0000000..830337f --- /dev/null +++ b/archive/hge/CxImage/ximahist.cpp @@ -0,0 +1,627 @@ +// xImaHist.cpp : histogram functions
+/* 28/01/2004 v1.00 - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_DSP
+
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::Histogram(int32_t* red, int32_t* green, int32_t* blue, int32_t* gray, int32_t colorspace)
+{
+ if (!pDib) return 0;
+ RGBQUAD color;
+
+ if (red) memset(red,0,256*sizeof(int32_t));
+ if (green) memset(green,0,256*sizeof(int32_t));
+ if (blue) memset(blue,0,256*sizeof(int32_t));
+ if (gray) memset(gray,0,256*sizeof(int32_t));
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ for(int32_t y=ymin; y<ymax; y++){
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ switch (colorspace){
+ case 1:
+ color = HSLtoRGB(BlindGetPixelColor(x,y));
+ break;
+ case 2:
+ color = YUVtoRGB(BlindGetPixelColor(x,y));
+ break;
+ case 3:
+ color = YIQtoRGB(BlindGetPixelColor(x,y));
+ break;
+ case 4:
+ color = XYZtoRGB(BlindGetPixelColor(x,y));
+ break;
+ default:
+ color = BlindGetPixelColor(x,y);
+ }
+
+ if (red) red[color.rgbRed]++;
+ if (green) green[color.rgbGreen]++;
+ if (blue) blue[color.rgbBlue]++;
+ if (gray) gray[(uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
+ }
+ }
+ }
+
+ int32_t n=0;
+ for (int32_t i=0; i<256; i++){
+ if (red && red[i]>n) n=red[i];
+ if (green && green[i]>n) n=green[i];
+ if (blue && blue[i]>n) n=blue[i];
+ if (gray && gray[i]>n) n=gray[i];
+ }
+
+ return n;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * HistogramStretch
+ * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels.
+ * \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%);
+ * \return true if everything is ok
+ * \author [dave] and [nipper]; changes [DP]
+ */
+bool CxImage::HistogramStretch(int32_t method, double threshold)
+{
+ if (!pDib) return false;
+
+ double dbScaler = 50.0/head.biHeight;
+ int32_t x,y;
+
+ if ((head.biBitCount==8) && IsGrayScale()){
+
+ double p[256];
+ memset(p, 0, 256*sizeof(double));
+ for (y=0; y<head.biHeight; y++)
+ {
+ info.nProgress = (int32_t)(y*dbScaler);
+ if (info.nEscape) break;
+ for (x=0; x<head.biWidth; x++) {
+ p[BlindGetPixelIndex(x, y)]++;
+ }
+ }
+
+ double maxh = 0;
+ for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
+ threshold *= maxh;
+ int32_t minc = 0;
+ while (minc<255 && p[minc]<=threshold) minc++;
+ int32_t maxc = 255;
+ while (maxc>0 && p[maxc]<=threshold) maxc--;
+
+ if (minc == 0 && maxc == 255) return true;
+ if (minc >= maxc) return true;
+
+ // calculate LUT
+ uint8_t lut[256];
+ for (x = 0; x <256; x++){
+ lut[x] = (uint8_t)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
+ }
+
+ for (y=0; y<head.biHeight; y++) {
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)(50.0+y*dbScaler);
+ for (x=0; x<head.biWidth; x++)
+ {
+ BlindSetPixelIndex(x, y, lut[BlindGetPixelIndex(x, y)]);
+ }
+ }
+ } else {
+ switch(method){
+ case 1:
+ { // <nipper>
+ double p[256];
+ memset(p, 0, 256*sizeof(double));
+ for (y=0; y<head.biHeight; y++)
+ {
+ info.nProgress = (int32_t)(y*dbScaler);
+ if (info.nEscape) break;
+ for (x=0; x<head.biWidth; x++) {
+ RGBQUAD color = BlindGetPixelColor(x, y);
+ p[color.rgbRed]++;
+ p[color.rgbBlue]++;
+ p[color.rgbGreen]++;
+ }
+ }
+ double maxh = 0;
+ for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
+ threshold *= maxh;
+ int32_t minc = 0;
+ while (minc<255 && p[minc]<=threshold) minc++;
+ int32_t maxc = 255;
+ while (maxc>0 && p[maxc]<=threshold) maxc--;
+
+ if (minc == 0 && maxc == 255) return true;
+ if (minc >= maxc) return true;
+
+ // calculate LUT
+ uint8_t lut[256];
+ for (x = 0; x <256; x++){
+ lut[x] = (uint8_t)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
+ }
+
+ // normalize image
+ for (y=0; y<head.biHeight; y++) {
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)(50.0+y*dbScaler);
+
+ for (x=0; x<head.biWidth; x++)
+ {
+ RGBQUAD color = BlindGetPixelColor(x, y);
+
+ color.rgbRed = lut[color.rgbRed];
+ color.rgbBlue = lut[color.rgbBlue];
+ color.rgbGreen = lut[color.rgbGreen];
+
+ BlindSetPixelColor(x, y, color);
+ }
+ }
+ }
+ break;
+ case 2:
+ { // <nipper>
+ double pR[256];
+ memset(pR, 0, 256*sizeof(double));
+ double pG[256];
+ memset(pG, 0, 256*sizeof(double));
+ double pB[256];
+ memset(pB, 0, 256*sizeof(double));
+ for (y=0; y<head.biHeight; y++)
+ {
+ info.nProgress = (int32_t)(y*dbScaler);
+ if (info.nEscape) break;
+ for (int32_t x=0; x<head.biWidth; x++) {
+ RGBQUAD color = BlindGetPixelColor(x, y);
+ pR[color.rgbRed]++;
+ pB[color.rgbBlue]++;
+ pG[color.rgbGreen]++;
+ }
+ }
+
+ double maxh = 0;
+ for (y=0; y<255; y++) if (maxh < pR[y]) maxh = pR[y];
+ double threshold2 = threshold*maxh;
+ int32_t minR = 0;
+ while (minR<255 && pR[minR]<=threshold2) minR++;
+ int32_t maxR = 255;
+ while (maxR>0 && pR[maxR]<=threshold2) maxR--;
+
+ maxh = 0;
+ for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y];
+ threshold2 = threshold*maxh;
+ int32_t minG = 0;
+ while (minG<255 && pG[minG]<=threshold2) minG++;
+ int32_t maxG = 255;
+ while (maxG>0 && pG[maxG]<=threshold2) maxG--;
+
+ maxh = 0;
+ for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y];
+ threshold2 = threshold*maxh;
+ int32_t minB = 0;
+ while (minB<255 && pB[minB]<=threshold2) minB++;
+ int32_t maxB = 255;
+ while (maxB>0 && pB[maxB]<=threshold2) maxB--;
+
+ if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
+ return true;
+
+ // calculate LUT
+ uint8_t lutR[256];
+ uint8_t range = maxR - minR;
+ if (range != 0) {
+ for (x = 0; x <256; x++){
+ lutR[x] = (uint8_t)max(0,min(255,(255 * (x - minR) / range)));
+ }
+ } else lutR[minR] = minR;
+
+ uint8_t lutG[256];
+ range = maxG - minG;
+ if (range != 0) {
+ for (x = 0; x <256; x++){
+ lutG[x] = (uint8_t)max(0,min(255,(255 * (x - minG) / range)));
+ }
+ } else lutG[minG] = minG;
+
+ uint8_t lutB[256];
+ range = maxB - minB;
+ if (range != 0) {
+ for (x = 0; x <256; x++){
+ lutB[x] = (uint8_t)max(0,min(255,(255 * (x - minB) / range)));
+ }
+ } else lutB[minB] = minB;
+
+ // normalize image
+ for (y=0; y<head.biHeight; y++)
+ {
+ info.nProgress = (int32_t)(50.0+y*dbScaler);
+ if (info.nEscape) break;
+
+ for (x=0; x<head.biWidth; x++)
+ {
+ RGBQUAD color = BlindGetPixelColor(x, y);
+
+ color.rgbRed = lutR[color.rgbRed];
+ color.rgbBlue = lutB[color.rgbBlue];
+ color.rgbGreen = lutG[color.rgbGreen];
+
+ BlindSetPixelColor(x, y, color);
+ }
+ }
+ }
+ break;
+ default:
+ { // <dave>
+ double p[256];
+ memset(p, 0, 256*sizeof(double));
+ for (y=0; y<head.biHeight; y++)
+ {
+ info.nProgress = (int32_t)(y*dbScaler);
+ if (info.nEscape) break;
+ for (x=0; x<head.biWidth; x++) {
+ RGBQUAD color = BlindGetPixelColor(x, y);
+ p[RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue)]++;
+ }
+ }
+
+ double maxh = 0;
+ for (y=0; y<255; y++) if (maxh < p[y]) maxh = p[y];
+ threshold *= maxh;
+ int32_t minc = 0;
+ while (minc<255 && p[minc]<=threshold) minc++;
+ int32_t maxc = 255;
+ while (maxc>0 && p[maxc]<=threshold) maxc--;
+
+ if (minc == 0 && maxc == 255) return true;
+ if (minc >= maxc) return true;
+
+ // calculate LUT
+ uint8_t lut[256];
+ for (x = 0; x <256; x++){
+ lut[x] = (uint8_t)max(0,min(255,(255 * (x - minc) / (maxc - minc))));
+ }
+
+ for(y=0; y<head.biHeight; y++){
+ info.nProgress = (int32_t)(50.0+y*dbScaler);
+ if (info.nEscape) break;
+ for(x=0; x<head.biWidth; x++){
+
+ RGBQUAD color = BlindGetPixelColor( x, y );
+ RGBQUAD yuvClr = RGBtoYUV(color);
+ yuvClr.rgbRed = lut[yuvClr.rgbRed];
+ color = YUVtoRGB(yuvClr);
+ BlindSetPixelColor( x, y, color );
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+// HistogramEqualize function by <dave> : dave(at)posortho(dot)com
+bool CxImage::HistogramEqualize()
+{
+ if (!pDib) return false;
+
+ int32_t histogram[256];
+ int32_t map[256];
+ int32_t equalize_map[256];
+ int32_t x, y, i, j;
+ RGBQUAD color;
+ RGBQUAD yuvClr;
+ uint32_t YVal, high, low;
+
+ memset( &histogram, 0, sizeof(int32_t) * 256 );
+ memset( &map, 0, sizeof(int32_t) * 256 );
+ memset( &equalize_map, 0, sizeof(int32_t) * 256 );
+
+ // form histogram
+ for(y=0; y < head.biHeight; y++){
+ info.nProgress = (int32_t)(50*y/head.biHeight);
+ if (info.nEscape) break;
+ for(x=0; x < head.biWidth; x++){
+ color = BlindGetPixelColor( x, y );
+ YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
+ histogram[YVal]++;
+ }
+ }
+
+ // integrate the histogram to get the equalization map.
+ j = 0;
+ for(i=0; i <= 255; i++){
+ j += histogram[i];
+ map[i] = j;
+ }
+
+ // equalize
+ low = map[0];
+ high = map[255];
+ if (low == high) return false;
+ for( i = 0; i <= 255; i++ ){
+ equalize_map[i] = (uint32_t)((((double)( map[i] - low ) ) * 255) / ( high - low ) );
+ }
+
+ // stretch the histogram
+ if(head.biClrUsed == 0){ // No Palette
+ for( y = 0; y < head.biHeight; y++ ){
+ info.nProgress = (int32_t)(50+50*y/head.biHeight);
+ if (info.nEscape) break;
+ for( x = 0; x < head.biWidth; x++ ){
+
+ color = BlindGetPixelColor( x, y );
+ yuvClr = RGBtoYUV(color);
+
+ yuvClr.rgbRed = (uint8_t)equalize_map[yuvClr.rgbRed];
+
+ color = YUVtoRGB(yuvClr);
+ BlindSetPixelColor( x, y, color );
+ }
+ }
+ } else { // Palette
+ for( i = 0; i < (int32_t)head.biClrUsed; i++ ){
+
+ color = GetPaletteColor((uint8_t)i);
+ yuvClr = RGBtoYUV(color);
+
+ yuvClr.rgbRed = (uint8_t)equalize_map[yuvClr.rgbRed];
+
+ color = YUVtoRGB(yuvClr);
+ SetPaletteColor( (uint8_t)i, color );
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+// HistogramNormalize function by <dave> : dave(at)posortho(dot)com
+bool CxImage::HistogramNormalize()
+{
+ if (!pDib) return false;
+
+ int32_t histogram[256];
+ int32_t threshold_intensity, intense;
+ int32_t x, y, i;
+ uint32_t normalize_map[256];
+ uint32_t high, low, YVal;
+
+ RGBQUAD color;
+ RGBQUAD yuvClr;
+
+ memset( &histogram, 0, sizeof( int32_t ) * 256 );
+ memset( &normalize_map, 0, sizeof( uint32_t ) * 256 );
+
+ // form histogram
+ for(y=0; y < head.biHeight; y++){
+ info.nProgress = (int32_t)(50*y/head.biHeight);
+ if (info.nEscape) break;
+ for(x=0; x < head.biWidth; x++){
+ color = BlindGetPixelColor( x, y );
+ YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
+ histogram[YVal]++;
+ }
+ }
+
+ // find histogram boundaries by locating the 1 percent levels
+ threshold_intensity = ( head.biWidth * head.biHeight) / 100;
+
+ intense = 0;
+ for( low = 0; low < 255; low++ ){
+ intense += histogram[low];
+ if( intense > threshold_intensity ) break;
+ }
+
+ intense = 0;
+ for( high = 255; high != 0; high--){
+ intense += histogram[ high ];
+ if( intense > threshold_intensity ) break;
+ }
+
+ if ( low == high ){
+ // Unreasonable contrast; use zero threshold to determine boundaries.
+ threshold_intensity = 0;
+ intense = 0;
+ for( low = 0; low < 255; low++){
+ intense += histogram[low];
+ if( intense > threshold_intensity ) break;
+ }
+ intense = 0;
+ for( high = 255; high != 0; high-- ){
+ intense += histogram [high ];
+ if( intense > threshold_intensity ) break;
+ }
+ }
+ if( low == high ) return false; // zero span bound
+
+ // Stretch the histogram to create the normalized image mapping.
+ for(i = 0; i <= 255; i++){
+ if ( i < (int32_t) low ){
+ normalize_map[i] = 0;
+ } else {
+ if(i > (int32_t) high)
+ normalize_map[i] = 255;
+ else
+ normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low );
+ }
+ }
+
+ // Normalize
+ if( head.biClrUsed == 0 ){
+ for( y = 0; y < head.biHeight; y++ ){
+ info.nProgress = (int32_t)(50+50*y/head.biHeight);
+ if (info.nEscape) break;
+ for( x = 0; x < head.biWidth; x++ ){
+
+ color = BlindGetPixelColor( x, y );
+ yuvClr = RGBtoYUV( color );
+
+ yuvClr.rgbRed = (uint8_t)normalize_map[yuvClr.rgbRed];
+
+ color = YUVtoRGB( yuvClr );
+ BlindSetPixelColor( x, y, color );
+ }
+ }
+ } else {
+ for(i = 0; i < (int32_t)head.biClrUsed; i++){
+
+ color = GetPaletteColor( (uint8_t)i );
+ yuvClr = RGBtoYUV( color );
+
+ yuvClr.rgbRed = (uint8_t)normalize_map[yuvClr.rgbRed];
+
+ color = YUVtoRGB( yuvClr );
+ SetPaletteColor( (uint8_t)i, color );
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+// HistogramLog function by <dave> : dave(at)posortho(dot)com
+bool CxImage::HistogramLog()
+{
+ if (!pDib) return false;
+
+ //q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|);
+ int32_t x, y, i;
+ RGBQUAD color;
+ RGBQUAD yuvClr;
+
+ uint32_t YVal, high = 1;
+
+ // Find Highest Luminance Value in the Image
+ if( head.biClrUsed == 0 ){ // No Palette
+ for(y=0; y < head.biHeight; y++){
+ info.nProgress = (int32_t)(50*y/head.biHeight);
+ if (info.nEscape) break;
+ for(x=0; x < head.biWidth; x++){
+ color = BlindGetPixelColor( x, y );
+ YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
+ if (YVal > high ) high = YVal;
+ }
+ }
+ } else { // Palette
+ for(i = 0; i < (int32_t)head.biClrUsed; i++){
+ color = GetPaletteColor((uint8_t)i);
+ YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
+ if (YVal > high ) high = YVal;
+ }
+ }
+
+ // Logarithm Operator
+ double k = 255.0 / ::log( 1.0 + (double)high );
+ if( head.biClrUsed == 0 ){
+ for( y = 0; y < head.biHeight; y++ ){
+ info.nProgress = (int32_t)(50+50*y/head.biHeight);
+ if (info.nEscape) break;
+ for( x = 0; x < head.biWidth; x++ ){
+
+ color = BlindGetPixelColor( x, y );
+ yuvClr = RGBtoYUV( color );
+
+ yuvClr.rgbRed = (uint8_t)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
+
+ color = YUVtoRGB( yuvClr );
+ BlindSetPixelColor( x, y, color );
+ }
+ }
+ } else {
+ for(i = 0; i < (int32_t)head.biClrUsed; i++){
+
+ color = GetPaletteColor( (uint8_t)i );
+ yuvClr = RGBtoYUV( color );
+
+ yuvClr.rgbRed = (uint8_t)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) );
+
+ color = YUVtoRGB( yuvClr );
+ SetPaletteColor( (uint8_t)i, color );
+ }
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// HistogramRoot function by <dave> : dave(at)posortho(dot)com
+bool CxImage::HistogramRoot()
+{
+ if (!pDib) return false;
+ //q(i,j) = sqrt(|p(i,j)|);
+
+ int32_t x, y, i;
+ RGBQUAD color;
+ RGBQUAD yuvClr;
+ double dtmp;
+ uint32_t YVal, high = 1;
+
+ // Find Highest Luminance Value in the Image
+ if( head.biClrUsed == 0 ){ // No Palette
+ for(y=0; y < head.biHeight; y++){
+ info.nProgress = (int32_t)(50*y/head.biHeight);
+ if (info.nEscape) break;
+ for(x=0; x < head.biWidth; x++){
+ color = BlindGetPixelColor( x, y );
+ YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
+ if (YVal > high ) high = YVal;
+ }
+ }
+ } else { // Palette
+ for(i = 0; i < (int32_t)head.biClrUsed; i++){
+ color = GetPaletteColor((uint8_t)i);
+ YVal = (uint32_t)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
+ if (YVal > high ) high = YVal;
+ }
+ }
+
+ // Root Operator
+ double k = 256.0 / ::sqrt( 1.0 + (double)high );
+ if( head.biClrUsed == 0 ){
+ for( y = 0; y < head.biHeight; y++ ){
+ info.nProgress = (int32_t)(50+50*y/head.biHeight);
+ if (info.nEscape) break;
+ for( x = 0; x < head.biWidth; x++ ){
+
+ color = BlindGetPixelColor( x, y );
+ yuvClr = RGBtoYUV( color );
+
+ dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
+ if ( dtmp > 255.0 ) dtmp = 255.0;
+ if ( dtmp < 0 ) dtmp = 0;
+ yuvClr.rgbRed = (uint8_t)dtmp;
+
+ color = YUVtoRGB( yuvClr );
+ BlindSetPixelColor( x, y, color );
+ }
+ }
+ } else {
+ for(i = 0; i < (int32_t)head.biClrUsed; i++){
+
+ color = GetPaletteColor( (uint8_t)i );
+ yuvClr = RGBtoYUV( color );
+
+ dtmp = k * ::sqrt( (double)yuvClr.rgbRed );
+ if ( dtmp > 255.0 ) dtmp = 255.0;
+ if ( dtmp < 0 ) dtmp = 0;
+ yuvClr.rgbRed = (uint8_t)dtmp;
+
+ color = YUVtoRGB( yuvClr );
+ SetPaletteColor( (uint8_t)i, color );
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif
diff --git a/archive/hge/CxImage/ximaico.cpp b/archive/hge/CxImage/ximaico.cpp new file mode 100644 index 0000000..a808697 --- /dev/null +++ b/archive/hge/CxImage/ximaico.cpp @@ -0,0 +1,470 @@ +/*
+ * File: ximaico.cpp
+ * Purpose: Platform Independent ICON Image Class Loader and Writer (MS version)
+ * 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximaico.h"
+
+#if CXIMAGE_SUPPORT_ICO
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageICO::Decode(CxFile *hFile)
+{
+ if (hFile==NULL) return false;
+
+ uint32_t off = hFile->Tell(); //<yuandi>
+ int32_t page=info.nFrame; //internal icon structure indexes
+
+ // read the first part of the header
+ ICONHEADER icon_header;
+ hFile->Read(&icon_header,sizeof(ICONHEADER),1);
+
+ icon_header.idType = m_ntohs(icon_header.idType);
+ icon_header.idCount = m_ntohs(icon_header.idCount);
+
+ // check if it's an icon or a cursor
+ if ((icon_header.idReserved == 0) && ((icon_header.idType == 1)||(icon_header.idType == 2))) {
+
+ info.nNumFrames = icon_header.idCount;
+
+ // load the icon descriptions
+ ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header.idCount * sizeof(ICONDIRENTRY));
+ int32_t c;
+ for (c = 0; c < icon_header.idCount; c++) {
+ hFile->Read(icon_list + c, sizeof(ICONDIRENTRY), 1);
+
+ icon_list[c].wPlanes = m_ntohs(icon_list[c].wPlanes);
+ icon_list[c].wBitCount = m_ntohs(icon_list[c].wBitCount);
+ icon_list[c].dwBytesInRes = m_ntohl(icon_list[c].dwBytesInRes);
+ icon_list[c].dwImageOffset = m_ntohl(icon_list[c].dwImageOffset);
+ }
+
+ if ((page>=0)&&(page<icon_header.idCount)){
+
+ if (info.nEscape == -1) {
+ // Return output dimensions only
+ head.biWidth = icon_list[page].bWidth;
+ head.biHeight = icon_list[page].bHeight;
+#if CXIMAGE_SUPPORT_PNG
+ if (head.biWidth==0 && head.biHeight==0)
+ { // Vista icon support
+ hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
+ CxImage png;
+ png.SetEscape(-1);
+ if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
+ Transfer(png);
+ info.nNumFrames = icon_header.idCount;
+ }
+ }
+#endif //CXIMAGE_SUPPORT_PNG
+ free(icon_list);
+ info.dwType = CXIMAGE_FORMAT_ICO;
+ return true;
+ }
+
+ // get the bit count for the colors in the icon <CoreyRLucier>
+ BITMAPINFOHEADER bih;
+ hFile->Seek(off + icon_list[page].dwImageOffset, SEEK_SET);
+
+ if (icon_list[page].bWidth==0 && icon_list[page].bHeight==0)
+ { // Vista icon support
+#if CXIMAGE_SUPPORT_PNG
+ CxImage png;
+ if (png.Decode(hFile,CXIMAGE_FORMAT_PNG)){
+ Transfer(png);
+ info.nNumFrames = icon_header.idCount;
+ }
+ SetType(CXIMAGE_FORMAT_ICO);
+#endif //CXIMAGE_SUPPORT_PNG
+ }
+ else
+ { // standard icon
+ hFile->Read(&bih,sizeof(BITMAPINFOHEADER),1);
+
+ bihtoh(&bih);
+
+ c = bih.biBitCount;
+
+ // allocate memory for one icon
+ Create(icon_list[page].bWidth,icon_list[page].bHeight, c, CXIMAGE_FORMAT_ICO); //image creation
+
+ // read the palette
+ RGBQUAD pal[256];
+ if (bih.biClrUsed)
+ hFile->Read(pal,bih.biClrUsed*sizeof(RGBQUAD), 1);
+ else
+ hFile->Read(pal,head.biClrUsed*sizeof(RGBQUAD), 1);
+
+ SetPalette(pal,head.biClrUsed); //palette assign
+
+ //read the icon
+ if (c<=24){
+ hFile->Read(info.pImage, head.biSizeImage, 1);
+ } else { // 32 bit icon
+ uint8_t* buf=(uint8_t*)malloc(4*head.biHeight*head.biWidth);
+ uint8_t* src = buf;
+ hFile->Read(buf, 4*head.biHeight*head.biWidth, 1);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (!AlphaIsValid()) AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ uint8_t* dst = GetBits(y);
+ for(int32_t x=0;x<head.biWidth;x++){
+ *dst++=src[0];
+ *dst++=src[1];
+ *dst++=src[2];
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaSet(x,y,src[3]);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ src+=4;
+ }
+ }
+ free(buf);
+ }
+ // apply the AND and XOR masks
+ int32_t maskwdt = ((head.biWidth+31) / 32) * 4; //line width of AND mask (always 1 Bpp)
+ int32_t masksize = head.biHeight * maskwdt; //size of mask
+ uint8_t *mask = (uint8_t *)malloc(masksize);
+ if (hFile->Read(mask, masksize, 1)){
+
+ bool bGoodMask=false;
+ for (int32_t im=0;im<masksize;im++){
+ if (mask[im]!=255){
+ bGoodMask=true;
+ break;
+ }
+ }
+
+ if (bGoodMask){
+#if CXIMAGE_SUPPORT_ALPHA
+ bool bNeedAlpha = false;
+ if (!AlphaIsValid()){
+ AlphaCreate();
+ } else {
+ bNeedAlpha=true; //32bit icon
+ }
+ int32_t x,y;
+ for (y = 0; y < head.biHeight; y++) {
+ for (x = 0; x < head.biWidth; x++) {
+ if (((mask[y*maskwdt+(x>>3)]>>(7-x%8))&0x01)){
+ AlphaSet(x,y,0);
+ bNeedAlpha=true;
+ }
+ }
+ }
+ if (!bNeedAlpha) AlphaDelete();
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ //check if there is only one transparent color
+ RGBQUAD cc,ct;
+ int32_t nTransColors=0;
+ int32_t nTransIndex=0;
+ for (y = 0; y < head.biHeight; y++){
+ for (x = 0; x < head.biWidth; x++){
+ if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
+ cc = GetPixelColor(x,y,false);
+ if (nTransColors==0){
+ nTransIndex = GetPixelIndex(x,y);
+ nTransColors++;
+ ct = cc;
+ } else {
+ if (memcmp(&cc, &ct, sizeof(RGBQUAD)) != 0){
+ nTransColors++;
+ }
+ }
+ }
+ }
+ }
+ if (nTransColors==1 && c<=8){
+ SetTransColor(ct);
+ SetTransIndex(nTransIndex);
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaDelete(); //because we have a unique transparent color in the image
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+
+ // <vho> - Transparency support w/o Alpha support
+ if (c <= 8){ // only for icons with less than 256 colors (XP icons need alpha).
+
+ // find a color index, which is not used in the image
+ // it is almost sure to find one, bcs. nobody uses all possible colors for an icon
+
+ uint8_t colorsUsed[256];
+ memset(colorsUsed, 0, sizeof(colorsUsed));
+
+ for (y = 0; y < head.biHeight; y++){
+ for (x = 0; x < head.biWidth; x++){
+ colorsUsed[BlindGetPixelIndex(x,y)] = 1;
+ }
+ }
+
+ int32_t iTransIdx = -1;
+ for (x = (int32_t)(head.biClrUsed-1); x>=0 ; x--){
+ if (colorsUsed[x] == 0){
+ iTransIdx = x; // this one is not in use. we may use it as transparent color
+ break;
+ }
+ }
+
+ // Go thru image and set unused color as transparent index if needed
+ if (iTransIdx >= 0){
+ bool bNeedTrans = false;
+ for (y = 0; y < head.biHeight; y++){
+ for (x = 0; x < head.biWidth; x++){
+ // AND mask (Each Byte represents 8 Pixels)
+ if (((mask[y*maskwdt+(x>>3)] >> (7-x%8)) & 0x01)){
+ // AND mask is set (!=0). This is a transparent part
+ SetPixelIndex(x, y, (uint8_t)iTransIdx);
+ bNeedTrans = true;
+ }
+ }
+ }
+ // set transparent index if needed
+ if (bNeedTrans) SetTransIndex(iTransIdx);
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaDelete(); //because we have a transparent color in the palette
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ } else {
+ SetTransIndex(0); //empty mask, set black as transparent color
+ Negative();
+ }
+ }
+ free(mask);
+ }
+ free(icon_list);
+ // icon has been loaded successfully!
+ return true;
+ }
+ free(icon_list);
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+// Thanks to <Alas>
+bool CxImageICO::Encode(CxFile * hFile, CxImage ** pImages, int32_t nPageCount)
+{
+ cx_try
+ {
+ if (hFile==NULL) cx_throw("invalid file pointer");
+ if (pImages==NULL || nPageCount<=0) cx_throw("multipage ICO, no images!");
+
+ int32_t i;
+ for (i=0; i<nPageCount; i++){
+ if (pImages[i]==NULL)
+ cx_throw("Bad image pointer");
+ if (!(pImages[i]->IsValid()))
+ cx_throw("Empty image");
+ }
+
+ CxImageICO ghost;
+ for (i=0; i<nPageCount; i++){ //write headers
+ ghost.Ghost(pImages[i]);
+ ghost.info.nNumFrames = nPageCount;
+ if (i==0) {
+ if (!ghost.Encode(hFile,false,nPageCount))
+ cx_throw("Error writing ICO file header");
+ }
+ if (!ghost.Encode(hFile,true,nPageCount))
+ cx_throw("Error saving ICO image header");
+ }
+ for (i=0; i<nPageCount; i++){ //write bodies
+ ghost.Ghost(pImages[i]);
+ ghost.info.nNumFrames = nPageCount;
+ if (!ghost.Encode(hFile,true,i))
+ cx_throw("Error saving ICO body");
+ }
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageICO::Encode(CxFile * hFile, bool bAppend, int32_t nPageCount)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+#if CXIMAGE_SUPPORT_PNG == 0
+ //check format limits
+ if ((head.biWidth>255)||(head.biHeight>255)){
+ strcpy(info.szLastError,"Can't save this image as icon");
+ return false;
+ }
+#endif
+
+ //prepare the palette struct
+ RGBQUAD* pal=GetPalette();
+ if (head.biBitCount<=8 && pal==NULL) return false;
+
+ int32_t maskwdt=((head.biWidth+31)/32)*4; //mask line width
+ int32_t masksize=head.biHeight * maskwdt; //size of mask
+ int32_t bitcount=head.biBitCount;
+ int32_t imagesize=head.biSizeImage;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid() && head.biClrUsed==0){
+ bitcount=32;
+ imagesize=4*head.biHeight*head.biWidth;
+ }
+#endif
+
+ //fill the icon headers
+ int32_t nPages = nPageCount;
+ if (nPages<1) nPages = 1;
+
+ ICONHEADER icon_header={0,1,nPages};
+
+ if (!bAppend)
+ m_dwImageOffset = sizeof(ICONHEADER) + nPages * sizeof(ICONDIRENTRY);
+
+ uint32_t dwBytesInRes = sizeof(BITMAPINFOHEADER)+head.biClrUsed*sizeof(RGBQUAD)+imagesize+masksize;
+
+ ICONDIRENTRY icon_list={
+ (uint8_t)head.biWidth,
+ (uint8_t)head.biHeight,
+ (uint8_t)head.biClrUsed,
+ 0, 0,
+ (uint16_t)bitcount,
+ dwBytesInRes,
+ m_dwImageOffset
+ };
+
+ BITMAPINFOHEADER bi={
+ sizeof(BITMAPINFOHEADER),
+ head.biWidth,
+ 2*head.biHeight,
+ 1,
+ (uint16_t)bitcount,
+ 0, imagesize,
+ 0, 0, 0, 0
+ };
+
+#if CXIMAGE_SUPPORT_PNG // Vista icon support
+ CxImage png(*this);
+ CxMemFile memfile;
+ if (head.biWidth>255 || head.biHeight>255){
+ icon_list.bWidth = icon_list.bHeight = 0;
+ memfile.Open();
+ png.Encode(&memfile,CXIMAGE_FORMAT_PNG);
+ icon_list.dwBytesInRes = dwBytesInRes = memfile.Size();
+ }
+#endif //CXIMAGE_SUPPORT_PNG
+
+ if (!bAppend){
+ icon_header.idType = m_ntohs(icon_header.idType);
+ icon_header.idCount = m_ntohs(icon_header.idCount);
+ hFile->Write(&icon_header,sizeof(ICONHEADER),1); //write the file header
+ icon_header.idType = m_ntohs(icon_header.idType);
+ icon_header.idCount = m_ntohs(icon_header.idCount);
+ }
+
+
+ if ((bAppend && nPageCount==info.nNumFrames) || (!bAppend && nPageCount==0)){
+ icon_list.wPlanes = m_ntohs(icon_list.wPlanes);
+ icon_list.wBitCount = m_ntohs(icon_list.wBitCount);
+ icon_list.dwBytesInRes = m_ntohl(icon_list.dwBytesInRes);
+ icon_list.dwImageOffset = m_ntohl(icon_list.dwImageOffset);
+ hFile->Write(&icon_list,sizeof(ICONDIRENTRY),1); //write the image entry
+ icon_list.wPlanes = m_ntohs(icon_list.wPlanes);
+ icon_list.wBitCount = m_ntohs(icon_list.wBitCount);
+ icon_list.dwBytesInRes = m_ntohl(icon_list.dwBytesInRes);
+ icon_list.dwImageOffset = m_ntohl(icon_list.dwImageOffset);
+
+ m_dwImageOffset += dwBytesInRes; //update offset for next header
+ }
+
+ if ((bAppend && nPageCount<info.nNumFrames) || (!bAppend && nPageCount==0))
+ {
+#if CXIMAGE_SUPPORT_PNG
+ if (icon_list.bWidth==0 && icon_list.bHeight==0) { // Vista icon support
+ hFile->Write(memfile.GetBuffer(false),dwBytesInRes,1);
+ } else
+#endif //CXIMAGE_SUPPORT_PNG
+ { // standard icon
+ bihtoh(&bi);
+ hFile->Write(&bi,sizeof(BITMAPINFOHEADER),1); //write the image header
+ bihtoh(&bi);
+
+ bool bTransparent = info.nBkgndIndex >= 0;
+ RGBQUAD ct = GetTransColor();
+ if (pal){
+ if (bTransparent) SetPaletteColor((uint8_t)info.nBkgndIndex,0,0,0,0);
+ hFile->Write(pal,head.biClrUsed*sizeof(RGBQUAD),1); //write palette
+ if (bTransparent) SetPaletteColor((uint8_t)info.nBkgndIndex,ct);
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid() && head.biClrUsed==0){
+ uint8_t* buf=(uint8_t*)malloc(imagesize);
+ uint8_t* dst = buf;
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ uint8_t* src = GetBits(y);
+ for(int32_t x=0;x<head.biWidth;x++){
+ *dst++=*src++;
+ *dst++=*src++;
+ *dst++=*src++;
+ *dst++=AlphaGet(x,y);
+ }
+ }
+ hFile->Write(buf,imagesize, 1);
+ free(buf);
+ } else {
+ hFile->Write(info.pImage,imagesize,1); //write image
+ }
+#else
+ hFile->Write(info.pImage,imagesize,1); //write image
+#endif
+
+ //save transparency mask
+ uint8_t* mask=(uint8_t*)calloc(masksize,1); //create empty AND/XOR masks
+ if (!mask) return false;
+
+ //prepare the variables to build the mask
+ uint8_t* iDst;
+ int32_t pos,i;
+ RGBQUAD c={0,0,0,0};
+ int32_t* pc = (int32_t*)&c;
+ int32_t* pct= (int32_t*)&ct;
+#if CXIMAGE_SUPPORT_ALPHA
+ bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
+ bool bAlphaIsValid = AlphaIsValid();
+#endif
+ //build the mask
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ for (int32_t x = 0; x < head.biWidth; x++) {
+ i=0;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (bAlphaIsValid && AlphaGet(x,y)==0) i=1;
+ if (bAlphaPaletteIsValid && BlindGetPixelColor(x,y).rgbReserved==0) i=1;
+#endif
+ c=GetPixelColor(x,y,false);
+ if (bTransparent && *pc==*pct) i=1;
+ iDst = mask + y*maskwdt + (x>>3);
+ pos = 7-x%8;
+ *iDst &= ~(0x01<<pos);
+ *iDst |= ((i & 0x01)<<pos);
+ }
+ }
+ //write AND/XOR masks
+ hFile->Write(mask,masksize,1);
+ free(mask);
+ }
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ICO
+
diff --git a/archive/hge/CxImage/ximaico.h b/archive/hge/CxImage/ximaico.h new file mode 100644 index 0000000..8d81b02 --- /dev/null +++ b/archive/hge/CxImage/ximaico.h @@ -0,0 +1,58 @@ +/*
+ * File: ximaico.h
+ * Purpose: ICON Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageICO (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ * ==========================================================
+ */
+#if !defined(__ximaICO_h)
+#define __ximaICO_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_ICO
+
+class CxImageICO: public CxImage
+{
+typedef struct tagIconDirectoryEntry {
+ uint8_t bWidth;
+ uint8_t bHeight;
+ uint8_t bColorCount;
+ uint8_t bReserved;
+ uint16_t wPlanes;
+ uint16_t wBitCount;
+ uint32_t dwBytesInRes;
+ uint32_t dwImageOffset;
+} ICONDIRENTRY;
+
+typedef struct tagIconDir {
+ uint16_t idReserved;
+ uint16_t idType;
+ uint16_t idCount;
+} ICONHEADER;
+
+public:
+ CxImageICO(): CxImage(CXIMAGE_FORMAT_ICO) {m_dwImageOffset=0;}
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile, bool bAppend=false, int32_t nPageCount=0);
+ bool Encode(CxFile * hFile, CxImage ** pImages, int32_t nPageCount);
+ bool Encode(FILE *hFile, bool bAppend=false, int32_t nPageCount=0)
+ { CxIOFile file(hFile); return Encode(&file,bAppend,nPageCount); }
+ bool Encode(FILE *hFile, CxImage ** pImages, int32_t nPageCount)
+ { CxIOFile file(hFile); return Encode(&file, pImages, nPageCount); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+protected:
+ uint32_t m_dwImageOffset;
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximainfo.cpp b/archive/hge/CxImage/ximainfo.cpp new file mode 100644 index 0000000..582d9ed --- /dev/null +++ b/archive/hge/CxImage/ximainfo.cpp @@ -0,0 +1,958 @@ +// ximainfo.cpp : main attributes
+/* 03/10/2004 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#if defined(_LINUX) || defined(__APPLE__)
+ #define _tcsnicmp(a,b,c) strcasecmp(a,b)
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return the color used for transparency, and/or for background color
+ */
+RGBQUAD CxImage::GetTransColor()
+{
+ if (head.biBitCount<24 && info.nBkgndIndex>=0) return GetPaletteColor((uint8_t)info.nBkgndIndex);
+ return info.nBkgndColor;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Gets the index used for transparency. Returns -1 for no transparancy.
+ */
+int32_t CxImage::GetTransIndex() const
+{
+ return info.nBkgndIndex;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the index used for transparency with 1, 4 and 8 bpp images. Set to -1 to remove the effect.
+ */
+void CxImage::SetTransIndex(int32_t idx)
+{
+ if (idx<(int32_t)head.biClrUsed)
+ info.nBkgndIndex = idx;
+ else
+ info.nBkgndIndex = 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the color used for transparency with 24 bpp images.
+ * You must call SetTransIndex(0) to enable the effect, SetTransIndex(-1) to disable it.
+ */
+void CxImage::SetTransColor(RGBQUAD rgb)
+{
+ rgb.rgbReserved=0;
+ info.nBkgndColor = rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::IsTransparent() const
+{
+ return info.nBkgndIndex>=0; // <vho>
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns true if the image has 256 colors or less.
+ */
+bool CxImage::IsIndexed() const
+{
+ return head.biClrUsed!=0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return 1 = indexed, 2 = RGB, 4 = RGBA
+ */
+uint8_t CxImage::GetColorType()
+{
+ uint8_t b = (uint8_t)((head.biBitCount>8) ? 2 /*COLORTYPE_COLOR*/ : 1 /*COLORTYPE_PALETTE*/);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) b = 4 /*COLORTYPE_ALPHA*/;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ return b;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return Resolution for TIFF, JPEG, PNG and BMP formats.
+ */
+int32_t CxImage::GetXDPI() const
+{
+ return info.xDPI;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return Resolution for TIFF, JPEG, PNG and BMP formats.
+ */
+int32_t CxImage::GetYDPI() const
+{
+ return info.yDPI;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Set resolution for TIFF, JPEG, PNG and BMP formats.
+ */
+void CxImage::SetXDPI(int32_t dpi)
+{
+ if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI;
+ info.xDPI = dpi;
+ head.biXPelsPerMeter = (int32_t) floor(dpi * 10000.0 / 254.0 + 0.5);
+ if (pDib) ((BITMAPINFOHEADER*)pDib)->biXPelsPerMeter = head.biXPelsPerMeter;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Set resolution for TIFF, JPEG, PNG and BMP formats.
+ */
+void CxImage::SetYDPI(int32_t dpi)
+{
+ if (dpi<=0) dpi = CXIMAGE_DEFAULT_DPI;
+ info.yDPI = dpi;
+ head.biYPelsPerMeter = (int32_t) floor(dpi * 10000.0 / 254.0 + 0.5);
+ if (pDib) ((BITMAPINFOHEADER*)pDib)->biYPelsPerMeter = head.biYPelsPerMeter;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa SetFlags
+ */
+uint32_t CxImage::GetFlags() const
+{
+ return info.dwFlags;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Image flags, for future use
+ * \param flags
+ * - 0x??00000 = reserved for 16 bit, CMYK, multilayer
+ * - 0x00??0000 = blend modes
+ * - 0x0000???? = layer id or user flags
+ *
+ * \param bLockReservedFlags protects the "reserved" and "blend modes" flags
+ */
+void CxImage::SetFlags(uint32_t flags, bool bLockReservedFlags)
+{
+ if (bLockReservedFlags) info.dwFlags = flags & 0x0000ffff;
+ else info.dwFlags = flags;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa SetCodecOption
+ */
+uint32_t CxImage::GetCodecOption(uint32_t imagetype)
+{
+ imagetype = GetTypeIndexFromId(imagetype);
+ if (imagetype==0){
+ imagetype = GetTypeIndexFromId(GetType());
+ }
+ return info.dwCodecOpt[imagetype];
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Encode option for GIF, TIF, JPG, PNG and RAW
+ * - GIF : 0 = LZW (default), 1 = none, 2 = RLE.
+ * - TIF : 0 = automatic (default), or a valid compression code as defined in "tiff.h" (COMPRESSION_NONE = 1, COMPRESSION_CCITTRLE = 2, ...)
+ * - JPG : valid values stored in enum CODEC_OPTION ( ENCODE_BASELINE = 0x01, ENCODE_PROGRESSIVE = 0x10, ...)
+ * - PNG : combination of interlace option and compression option
+ * interlace option : 1 = interlace, 0 = no interlace
+ * compression option : 2 = no compression, 4 = best speed, 6 = best compression, 8 = default compression
+ * default is no interlace and default compression
+ * example : 5 = 1+4 = interlace + best speed
+ * - RAW : valid values stored in enum CODEC_OPTION ( DECODE_QUALITY_LIN = 0x00, DECODE_QUALITY_VNG = 0x01, ...)
+ *
+ * \return true if everything is ok
+ */
+bool CxImage::SetCodecOption(uint32_t opt, uint32_t imagetype)
+{
+ imagetype = GetTypeIndexFromId(imagetype);
+ if (imagetype==0){
+ imagetype = GetTypeIndexFromId(GetType());
+ }
+ info.dwCodecOpt[imagetype] = opt;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return internal hDib object..
+ */
+void* CxImage::GetDIB() const
+{
+ return pDib;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::GetHeight() const
+{
+ return head.biHeight;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::GetWidth() const
+{
+ return head.biWidth;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return uint32_t aligned width of the image.
+ */
+uint32_t CxImage::GetEffWidth() const
+{
+ return info.dwEffWidth;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return 2, 16, 256; 0 for RGB images.
+ */
+uint32_t CxImage::GetNumColors() const
+{
+ return head.biClrUsed;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return: 1, 4, 8, 24.
+ */
+uint16_t CxImage::GetBpp() const
+{
+ return head.biBitCount;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return original image format
+ * \sa ENUM_CXIMAGE_FORMATS.
+ */
+uint32_t CxImage::GetType() const
+{
+ return info.dwType;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * change image format identifier
+ * \sa ENUM_CXIMAGE_FORMATS.
+ */
+bool CxImage::SetType(uint32_t type)
+{
+ switch (type){
+#if CXIMAGE_SUPPORT_BMP
+ case CXIMAGE_FORMAT_BMP:
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ case CXIMAGE_FORMAT_GIF:
+#endif
+#if CXIMAGE_SUPPORT_JPG
+ case CXIMAGE_FORMAT_JPG:
+#endif
+#if CXIMAGE_SUPPORT_PNG
+ case CXIMAGE_FORMAT_PNG:
+#endif
+#if CXIMAGE_SUPPORT_MNG
+ case CXIMAGE_FORMAT_MNG:
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ case CXIMAGE_FORMAT_ICO:
+#endif
+#if CXIMAGE_SUPPORT_TIF
+ case CXIMAGE_FORMAT_TIF:
+#endif
+#if CXIMAGE_SUPPORT_TGA
+ case CXIMAGE_FORMAT_TGA:
+#endif
+#if CXIMAGE_SUPPORT_PCX
+ case CXIMAGE_FORMAT_PCX:
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+ case CXIMAGE_FORMAT_WBMP:
+#endif
+#if CXIMAGE_SUPPORT_WMF
+ case CXIMAGE_FORMAT_WMF:
+#endif
+#if CXIMAGE_SUPPORT_JBG
+ case CXIMAGE_FORMAT_JBG:
+#endif
+#if CXIMAGE_SUPPORT_JP2
+ case CXIMAGE_FORMAT_JP2:
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ case CXIMAGE_FORMAT_JPC:
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ case CXIMAGE_FORMAT_PGX:
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ case CXIMAGE_FORMAT_PNM:
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ case CXIMAGE_FORMAT_RAS:
+#endif
+#if CXIMAGE_SUPPORT_SKA
+ case CXIMAGE_FORMAT_SKA:
+#endif
+#if CXIMAGE_SUPPORT_RAW
+ case CXIMAGE_FORMAT_RAW:
+#endif
+#if CXIMAGE_SUPPORT_PSD
+ case CXIMAGE_FORMAT_PSD:
+#endif
+ info.dwType = type;
+ return true;
+ case CXIMAGE_FORMAT_UNKNOWN:
+ default:
+ info.dwType = CXIMAGE_FORMAT_UNKNOWN;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::GetNumTypes()
+{
+ return CMAX_IMAGE_FORMATS-1;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::GetTypeIdFromName(const TCHAR* ext)
+{
+#if CXIMAGE_SUPPORT_BMP
+ if (_tcsnicmp(ext,_T("bmp"),3)==0 ) return CXIMAGE_FORMAT_BMP;
+#endif
+#if CXIMAGE_SUPPORT_JPG
+ if (_tcsnicmp(ext,_T("jpg"),3)==0 ||
+ _tcsnicmp(ext,_T("jpe"),3)==0 ||
+ _tcsnicmp(ext,_T("jfi"),3)==0 ) return CXIMAGE_FORMAT_JPG;
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ if (_tcsnicmp(ext,_T("gif"),3)==0 ) return CXIMAGE_FORMAT_GIF;
+#endif
+#if CXIMAGE_SUPPORT_PNG
+ if (_tcsnicmp(ext,_T("png"),3)==0 ) return CXIMAGE_FORMAT_PNG;
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ if (_tcsnicmp(ext,_T("ico"),3)==0 ||
+ _tcsnicmp(ext,_T("cur"),3)==0 ) return CXIMAGE_FORMAT_ICO;
+#endif
+#if CXIMAGE_SUPPORT_TIF
+ if (_tcsnicmp(ext,_T("tif"),3)==0 ) return CXIMAGE_FORMAT_TIF;
+#endif
+#if CXIMAGE_SUPPORT_TGA
+ if (_tcsnicmp(ext,_T("tga"),3)==0 ) return CXIMAGE_FORMAT_TGA;
+#endif
+#if CXIMAGE_SUPPORT_PCX
+ if (_tcsnicmp(ext,_T("pcx"),3)==0 ) return CXIMAGE_FORMAT_PCX;
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+ if (_tcsnicmp(ext,_T("wbm"),3)==0 ) return CXIMAGE_FORMAT_WBMP;
+#endif
+#if CXIMAGE_SUPPORT_WMF
+ if (_tcsnicmp(ext,_T("wmf"),3)==0 ||
+ _tcsnicmp(ext,_T("emf"),3)==0 ) return CXIMAGE_FORMAT_WMF;
+#endif
+#if CXIMAGE_SUPPORT_JP2
+ if (_tcsnicmp(ext,_T("jp2"),3)==0 ||
+ _tcsnicmp(ext,_T("j2k"),3)==0 ) return CXIMAGE_FORMAT_JP2;
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ if (_tcsnicmp(ext,_T("jpc"),3)==0 ||
+ _tcsnicmp(ext,_T("j2c"),3)==0 ) return CXIMAGE_FORMAT_JPC;
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ if (_tcsnicmp(ext,_T("pgx"),3)==0 ) return CXIMAGE_FORMAT_PGX;
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ if (_tcsnicmp(ext,_T("ras"),3)==0 ) return CXIMAGE_FORMAT_RAS;
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ if (_tcsnicmp(ext,_T("pnm"),3)==0 ||
+ _tcsnicmp(ext,_T("pgm"),3)==0 ||
+ _tcsnicmp(ext,_T("ppm"),3)==0 ) return CXIMAGE_FORMAT_PNM;
+#endif
+#if CXIMAGE_SUPPORT_JBG
+ if (_tcsnicmp(ext,_T("jbg"),3)==0 ) return CXIMAGE_FORMAT_JBG;
+#endif
+#if CXIMAGE_SUPPORT_MNG
+ if (_tcsnicmp(ext,_T("mng"),3)==0 ||
+ _tcsnicmp(ext,_T("jng"),3)==0 ) return CXIMAGE_FORMAT_MNG;
+#endif
+#if CXIMAGE_SUPPORT_SKA
+ if (_tcsnicmp(ext,_T("ska"),3)==0 ) return CXIMAGE_FORMAT_SKA;
+#endif
+#if CXIMAGE_SUPPORT_PSD
+ if (_tcsnicmp(ext,_T("psd"),3)==0 ) return CXIMAGE_FORMAT_PSD;
+#endif
+#if CXIMAGE_SUPPORT_RAW
+ if (_tcsnicmp(ext,_T("nef"),3)==0 ||
+ _tcsnicmp(ext,_T("crw"),3)==0 ||
+ _tcsnicmp(ext,_T("cr2"),3)==0 ||
+ _tcsnicmp(ext,_T("dng"),3)==0 ||
+ _tcsnicmp(ext,_T("arw"),3)==0 ||
+ _tcsnicmp(ext,_T("erf"),3)==0 ||
+ _tcsnicmp(ext,_T("3fr"),3)==0 ||
+ _tcsnicmp(ext,_T("dcr"),3)==0 ||
+ _tcsnicmp(ext,_T("raw"),3)==0 ||
+ _tcsnicmp(ext,_T("x3f"),3)==0 ||
+ _tcsnicmp(ext,_T("mef"),3)==0 ||
+ _tcsnicmp(ext,_T("raf"),3)==0 ||
+ _tcsnicmp(ext,_T("mrw"),3)==0 ||
+ _tcsnicmp(ext,_T("pef"),3)==0 ||
+ _tcsnicmp(ext,_T("sr2"),3)==0 ||
+ _tcsnicmp(ext,_T("orf"),3)==0 ) return CXIMAGE_FORMAT_RAW;
+#endif
+
+ return CXIMAGE_FORMAT_UNKNOWN;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::GetTypeIdFromIndex(const uint32_t index)
+{
+ uint32_t n;
+
+ n=0; if (index == n) return CXIMAGE_FORMAT_UNKNOWN;
+#if CXIMAGE_SUPPORT_BMP
+ n++; if (index == n) return CXIMAGE_FORMAT_BMP;
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ n++; if (index == n) return CXIMAGE_FORMAT_GIF;
+#endif
+#if CXIMAGE_SUPPORT_JPG
+ n++; if (index == n) return CXIMAGE_FORMAT_JPG;
+#endif
+#if CXIMAGE_SUPPORT_PNG
+ n++; if (index == n) return CXIMAGE_FORMAT_PNG;
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ n++; if (index == n) return CXIMAGE_FORMAT_ICO;
+#endif
+#if CXIMAGE_SUPPORT_TIF
+ n++; if (index == n) return CXIMAGE_FORMAT_TIF;
+#endif
+#if CXIMAGE_SUPPORT_TGA
+ n++; if (index == n) return CXIMAGE_FORMAT_TGA;
+#endif
+#if CXIMAGE_SUPPORT_PCX
+ n++; if (index == n) return CXIMAGE_FORMAT_PCX;
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+ n++; if (index == n) return CXIMAGE_FORMAT_WBMP;
+#endif
+#if CXIMAGE_SUPPORT_WMF
+ n++; if (index == n) return CXIMAGE_FORMAT_WMF;
+#endif
+#if CXIMAGE_SUPPORT_JP2
+ n++; if (index == n) return CXIMAGE_FORMAT_JP2;
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ n++; if (index == n) return CXIMAGE_FORMAT_JPC;
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ n++; if (index == n) return CXIMAGE_FORMAT_PGX;
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ n++; if (index == n) return CXIMAGE_FORMAT_PNM;
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ n++; if (index == n) return CXIMAGE_FORMAT_RAS;
+#endif
+#if CXIMAGE_SUPPORT_JBG
+ n++; if (index == n) return CXIMAGE_FORMAT_JBG;
+#endif
+#if CXIMAGE_SUPPORT_MNG
+ n++; if (index == n) return CXIMAGE_FORMAT_MNG;
+#endif
+#if CXIMAGE_SUPPORT_SKA
+ n++; if (index == n) return CXIMAGE_FORMAT_SKA;
+#endif
+#if CXIMAGE_SUPPORT_RAW
+ n++; if (index == n) return CXIMAGE_FORMAT_RAW;
+#endif
+#if CXIMAGE_SUPPORT_PSD
+ n++; if (index == n) return CXIMAGE_FORMAT_PSD;
+#endif
+
+ return CXIMAGE_FORMAT_UNKNOWN;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::GetTypeIndexFromId(const uint32_t id)
+{
+ uint32_t n;
+
+ n=0; if (id == CXIMAGE_FORMAT_UNKNOWN) return n;
+#if CXIMAGE_SUPPORT_BMP
+ n++; if (id == CXIMAGE_FORMAT_BMP) return n;
+#endif
+#if CXIMAGE_SUPPORT_GIF
+ n++; if (id == CXIMAGE_FORMAT_GIF) return n;
+#endif
+#if CXIMAGE_SUPPORT_JPG
+ n++; if (id == CXIMAGE_FORMAT_JPG) return n;
+#endif
+#if CXIMAGE_SUPPORT_PNG
+ n++; if (id == CXIMAGE_FORMAT_PNG) return n;
+#endif
+#if CXIMAGE_SUPPORT_ICO
+ n++; if (id == CXIMAGE_FORMAT_ICO) return n;
+#endif
+#if CXIMAGE_SUPPORT_TIF
+ n++; if (id == CXIMAGE_FORMAT_TIF) return n;
+#endif
+#if CXIMAGE_SUPPORT_TGA
+ n++; if (id == CXIMAGE_FORMAT_TGA) return n;
+#endif
+#if CXIMAGE_SUPPORT_PCX
+ n++; if (id == CXIMAGE_FORMAT_PCX) return n;
+#endif
+#if CXIMAGE_SUPPORT_WBMP
+ n++; if (id == CXIMAGE_FORMAT_WBMP) return n;
+#endif
+#if CXIMAGE_SUPPORT_WMF
+ n++; if (id == CXIMAGE_FORMAT_WMF) return n;
+#endif
+#if CXIMAGE_SUPPORT_JP2
+ n++; if (id == CXIMAGE_FORMAT_JP2) return n;
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ n++; if (id == CXIMAGE_FORMAT_JPC) return n;
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ n++; if (id == CXIMAGE_FORMAT_PGX) return n;
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ n++; if (id == CXIMAGE_FORMAT_PNM) return n;
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ n++; if (id == CXIMAGE_FORMAT_RAS) return n;
+#endif
+#if CXIMAGE_SUPPORT_JBG
+ n++; if (id == CXIMAGE_FORMAT_JBG) return n;
+#endif
+#if CXIMAGE_SUPPORT_MNG
+ n++; if (id == CXIMAGE_FORMAT_MNG) return n;
+#endif
+#if CXIMAGE_SUPPORT_SKA
+ n++; if (id == CXIMAGE_FORMAT_SKA) return n;
+#endif
+#if CXIMAGE_SUPPORT_RAW
+ n++; if (id == CXIMAGE_FORMAT_RAW) return n;
+#endif
+#if CXIMAGE_SUPPORT_PSD
+ n++; if (id == CXIMAGE_FORMAT_PSD) return n;
+#endif
+
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return current frame delay in milliseconds. Only for GIF and MNG formats.
+ */
+uint32_t CxImage::GetFrameDelay() const
+{
+ return info.dwFrameDelay;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets current frame delay. Only for GIF format.
+ * \param d = delay in milliseconds
+ */
+void CxImage::SetFrameDelay(uint32_t d)
+{
+ info.dwFrameDelay=d;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::GetOffset(int32_t *x,int32_t *y)
+{
+ *x=info.xOffset;
+ *y=info.yOffset;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetOffset(int32_t x,int32_t y)
+{
+ info.xOffset=x;
+ info.yOffset=y;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa SetJpegQuality, GetJpegQualityF
+ * \author [DP]; changes [Stefan Schürmans]
+ */
+uint8_t CxImage::GetJpegQuality() const
+{
+ return (uint8_t)(info.fQuality + 0.5f);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa SetJpegQuality, GetJpegQuality
+ * \author [Stefan Schürmans]
+ */
+float CxImage::GetJpegQualityF() const
+{
+ return info.fQuality;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * quality level for JPEG and JPEG2000
+ * \param q: can be from 0 to 100
+ * \author [DP]; changes [Stefan Schürmans]
+ */
+void CxImage::SetJpegQuality(uint8_t q){
+ info.fQuality = (float)q;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * quality level for JPEG and JPEG2000
+ * necessary for JPEG2000 when quality is between 0.0 and 1.0
+ * \param q: can be from 0.0 to 100.0
+ * \author [Stefan Schürmans]
+ */
+void CxImage::SetJpegQualityF(float q){
+ if (q>0) info.fQuality = q;
+ else info.fQuality = 0.0f;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa SetJpegScale
+ */
+uint8_t CxImage::GetJpegScale() const
+{
+ return info.nJpegScale;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * scaling down during JPEG decoding valid numbers are 1, 2, 4, 8
+ * \author [ignacio]
+ */
+void CxImage::SetJpegScale(uint8_t q){
+ info.nJpegScale = q;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Used to monitor the slow loops.
+ * \return value is from 0 to 100.
+ * \sa SetProgress
+ */
+int32_t CxImage::GetProgress() const
+{
+ return info.nProgress;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return the escape code.
+ * \sa SetEscape
+ */
+int32_t CxImage::GetEscape() const
+{
+ return info.nEscape;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Forces the value of the internal progress variable.
+ * \param p should be from 0 to 100.
+ * \sa GetProgress
+ */
+void CxImage::SetProgress(int32_t p)
+{
+ info.nProgress = p;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Used to quit the slow loops or the codecs.
+ * - SetEscape(-1) before Decode forces the function to exit, right after
+ * the image width and height are available ( for bmp, jpg, gif, tif )
+ */
+void CxImage::SetEscape(int32_t i)
+{
+ info.nEscape = i;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the image is correctly initializated.
+ */
+bool CxImage::IsValid() const
+{
+ return pDib!=0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * True if the image is enabled for painting.
+ */
+bool CxImage::IsEnabled() const
+{
+ return info.bEnabled;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Enables/disables the image.
+ */
+void CxImage::Enable(bool enable)
+{
+ info.bEnabled=enable;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * This function must be used after a Decode() / Load() call.
+ * Use the sequence SetFrame(-1); Load(...); GetNumFrames();
+ * to get the number of images without loading the first image.
+ * \return the number of images in the file.
+ */
+int32_t CxImage::GetNumFrames() const
+{
+ return info.nNumFrames;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return the current selected image (zero-based index).
+ */
+int32_t CxImage::GetFrame() const
+{
+ return info.nFrame;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the image number that the next Decode() / Load() call will load
+ */
+void CxImage::SetFrame(int32_t nFrame){
+ info.nFrame=nFrame;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the method for drawing the frame related to others
+ * \sa GetDisposalMethod
+ */
+void CxImage::SetDisposalMethod(uint8_t dm)
+{ info.dispmeth=dm; }
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Gets the method for drawing the frame related to others
+ * Values : 0 - No disposal specified. The decoder is
+ * not required to take any action.
+ * 1 - Do not dispose. The graphic is to be left
+ * in place.
+ * 2 - Restore to background color. The area used by the
+ * graphic must be restored to the background color.
+ * 3 - Restore to previous. The decoder is required to
+ * restore the area overwritten by the graphic with
+ * what was there prior to rendering the graphic.
+ * 4-7 - To be defined.
+ */
+uint8_t CxImage::GetDisposalMethod() const
+{ return info.dispmeth; }
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::GetRetreiveAllFrames() const
+{ return info.bGetAllFrames; }
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetRetreiveAllFrames(bool flag)
+{ info.bGetAllFrames = flag; }
+////////////////////////////////////////////////////////////////////////////////
+CxImage * CxImage::GetFrame(int32_t nFrame) const
+{
+ if ( ppFrames == NULL) return NULL;
+ if ( info.nNumFrames == 0) return NULL;
+ if ( nFrame >= info.nNumFrames ) return NULL;
+ if ( nFrame < 0) nFrame = info.nNumFrames - 1;
+ return ppFrames[nFrame];
+}
+////////////////////////////////////////////////////////////////////////////////
+int16_t CxImage::m_ntohs(const int16_t word)
+{
+ if (info.bLittleEndianHost) return word;
+ return ( (word & 0xff) << 8 ) | ( (word >> 8) & 0xff );
+}
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::m_ntohl(const int32_t dword)
+{
+ if (info.bLittleEndianHost) return dword;
+ return ((dword & 0xff) << 24 ) | ((dword & 0xff00) << 8 ) |
+ ((dword >> 8) & 0xff00) | ((dword >> 24) & 0xff);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::bihtoh(BITMAPINFOHEADER* bih)
+{
+ bih->biSize = m_ntohl(bih->biSize);
+ bih->biWidth = m_ntohl(bih->biWidth);
+ bih->biHeight = m_ntohl(bih->biHeight);
+ bih->biPlanes = m_ntohs(bih->biPlanes);
+ bih->biBitCount = m_ntohs(bih->biBitCount);
+ bih->biCompression = m_ntohl(bih->biCompression);
+ bih->biSizeImage = m_ntohl(bih->biSizeImage);
+ bih->biXPelsPerMeter = m_ntohl(bih->biXPelsPerMeter);
+ bih->biYPelsPerMeter = m_ntohl(bih->biYPelsPerMeter);
+ bih->biClrUsed = m_ntohl(bih->biClrUsed);
+ bih->biClrImportant = m_ntohl(bih->biClrImportant);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the last reported error.
+ */
+const char* CxImage::GetLastError()
+{
+ return info.szLastError;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::DumpSize()
+{
+ uint32_t n;
+ n = sizeof(BITMAPINFOHEADER) + sizeof(CXIMAGEINFO) + GetSize();
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha){
+ n += 1 + head.biWidth * head.biHeight;
+ } else n++;
+#endif
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (pSelection){
+ n += 1 + head.biWidth * head.biHeight;
+ } else n++;
+#endif
+
+#if CXIMAGE_SUPPORT_LAYERS
+ if (ppLayers){
+ for (int32_t m=0; m<GetNumLayers(); m++){
+ if (GetLayer(m)){
+ n += 1 + GetLayer(m)->DumpSize();
+ }
+ }
+ } else n++;
+#endif
+
+ if (ppFrames){
+ for (int32_t m=0; m<GetNumFrames(); m++){
+ if (GetFrame(m)){
+ n += 1 + GetFrame(m)->DumpSize();
+ }
+ }
+ } else n++;
+
+ return n;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::Dump(uint8_t * dst)
+{
+ if (!dst) return 0;
+
+ memcpy(dst,&head,sizeof(BITMAPINFOHEADER));
+ dst += sizeof(BITMAPINFOHEADER);
+
+ memcpy(dst,&info,sizeof(CXIMAGEINFO));
+ dst += sizeof(CXIMAGEINFO);
+
+ memcpy(dst,pDib,GetSize());
+ dst += GetSize();
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha){
+ memset(dst++, 1, 1);
+ memcpy(dst,pAlpha,head.biWidth * head.biHeight);
+ dst += head.biWidth * head.biHeight;
+ } else {
+ memset(dst++, 0, 1);
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (pSelection){
+ memset(dst++, 1, 1);
+ memcpy(dst,pSelection,head.biWidth * head.biHeight);
+ dst += head.biWidth * head.biHeight;
+ } else {
+ memset(dst++, 0, 1);
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_LAYERS
+ if (ppLayers){
+ memset(dst++, 1, 1);
+ for (int32_t m=0; m<GetNumLayers(); m++){
+ if (GetLayer(m)){
+ dst += GetLayer(m)->Dump(dst);
+ }
+ }
+ } else {
+ memset(dst++, 0, 1);
+ }
+#endif
+
+ if (ppFrames){
+ memset(dst++, 1, 1);
+ for (int32_t m=0; m<GetNumFrames(); m++){
+ if (GetFrame(m)){
+ dst += GetFrame(m)->Dump(dst);
+ }
+ }
+ } else {
+ memset(dst++, 0, 1);
+ }
+
+ return DumpSize();
+}
+////////////////////////////////////////////////////////////////////////////////
+uint32_t CxImage::UnDump(const uint8_t * src)
+{
+ if (!src)
+ return 0;
+ if (!Destroy())
+ return 0;
+ if (!DestroyFrames())
+ return 0;
+
+ uint32_t n = 0;
+
+ memcpy(&head,src,sizeof(BITMAPINFOHEADER));
+ n += sizeof(BITMAPINFOHEADER);
+
+ memcpy(&info,&src[n],sizeof(CXIMAGEINFO));
+ n += sizeof(CXIMAGEINFO);
+
+ if (!Create(head.biWidth, head.biHeight, head.biBitCount, info.dwType))
+ return 0;
+
+ memcpy(pDib,&src[n],GetSize());
+ n += GetSize();
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (src[n++]){
+ if (AlphaCreate()){
+ memcpy(pAlpha, &src[n], head.biWidth * head.biHeight);
+ }
+ n += head.biWidth * head.biHeight;
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (src[n++]){
+ RECT box = info.rSelectionBox;
+ if (SelectionCreate()){
+ info.rSelectionBox = box;
+ memcpy(pSelection, &src[n], head.biWidth * head.biHeight);
+ }
+ n += head.biWidth * head.biHeight;
+ }
+#endif
+
+#if CXIMAGE_SUPPORT_LAYERS
+ if (src[n++]){
+ ppLayers = new CxImage*[info.nNumLayers];
+ for (int32_t m=0; m<GetNumLayers(); m++){
+ ppLayers[m] = new CxImage();
+ n += ppLayers[m]->UnDump(&src[n]);
+ }
+ }
+#endif
+
+ if (src[n++]){
+ ppFrames = new CxImage*[info.nNumFrames];
+ for (int32_t m=0; m<GetNumFrames(); m++){
+ ppFrames[m] = new CxImage();
+ n += ppFrames[m]->UnDump(&src[n]);
+ }
+ }
+
+ return n;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \return A.BBCCCDDDD
+ * - A = main version
+ * - BB = main revision
+ * - CCC = minor revision (letter)
+ * - DDDD = experimental revision
+ */
+const float CxImage::GetVersionNumber()
+{
+ return 7.000000000f;
+}
+////////////////////////////////////////////////////////////////////////////////
+const TCHAR* CxImage::GetVersion()
+{
+ static const TCHAR CxImageVersion[] = _T("CxImage 7.0.0");
+ return (CxImageVersion);
+}
+////////////////////////////////////////////////////////////////////////////////
diff --git a/archive/hge/CxImage/ximaint.cpp b/archive/hge/CxImage/ximaint.cpp new file mode 100644 index 0000000..5f93038 --- /dev/null +++ b/archive/hge/CxImage/ximaint.cpp @@ -0,0 +1,1046 @@ +// xImaInt.cpp : interpolation functions
+/* 02/2004 - Branko Brevensek
+ * CxImage version 7.0.0 31/Dec/2010 - Davide Pizzolato - www.xdp.it
+ */
+
+#include "ximage.h"
+#include "ximath.h"
+
+#if CXIMAGE_SUPPORT_INTERPOLATION
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Recalculates coordinates according to specified overflow method.
+ * If pixel (x,y) lies within image, nothing changes.
+ *
+ * \param x, y - coordinates of pixel
+ * \param ofMethod - overflow method
+ *
+ * \return x, y - new coordinates (pixel (x,y) now lies inside image)
+ *
+ * \author ***bd*** 2.2004
+ */
+void CxImage::OverflowCoordinates(int32_t &x, int32_t &y, OverflowMethod const ofMethod)
+{
+ if (IsInside(x,y)) return; //if pixel is within bounds, no change
+ switch (ofMethod) {
+ case OM_REPEAT:
+ //clip coordinates
+ x=max(x,0); x=min(x, head.biWidth-1);
+ y=max(y,0); y=min(y, head.biHeight-1);
+ break;
+ case OM_WRAP:
+ //wrap coordinates
+ x = x % head.biWidth;
+ y = y % head.biHeight;
+ if (x<0) x = head.biWidth + x;
+ if (y<0) y = head.biHeight + y;
+ break;
+ case OM_MIRROR:
+ //mirror pixels near border
+ if (x<0) x=((-x) % head.biWidth);
+ else if (x>=head.biWidth) x=head.biWidth-(x % head.biWidth + 1);
+ if (y<0) y=((-y) % head.biHeight);
+ else if (y>=head.biHeight) y=head.biHeight-(y % head.biHeight + 1);
+ break;
+ default:
+ return;
+ }//switch
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * See OverflowCoordinates for integer version
+ * \author ***bd*** 2.2004
+ */
+void CxImage::OverflowCoordinates(float &x, float &y, OverflowMethod const ofMethod)
+{
+ if (x>=0 && x<head.biWidth && y>=0 && y<head.biHeight) return; //if pixel is within bounds, no change
+ switch (ofMethod) {
+ case OM_REPEAT:
+ //clip coordinates
+ x=max(x,0); x=min(x, head.biWidth-1);
+ y=max(y,0); y=min(y, head.biHeight-1);
+ break;
+ case OM_WRAP:
+ //wrap coordinates
+ x = (float)fmod(x, (float) head.biWidth);
+ y = (float)fmod(y, (float) head.biHeight);
+ if (x<0) x = head.biWidth + x;
+ if (y<0) y = head.biHeight + y;
+ break;
+ case OM_MIRROR:
+ //mirror pixels near border
+ if (x<0) x=(float)fmod(-x, (float) head.biWidth);
+ else if (x>=head.biWidth) x=head.biWidth-((float)fmod(x, (float) head.biWidth) + 1);
+ if (y<0) y=(float)fmod(-y, (float) head.biHeight);
+ else if (y>=head.biHeight) y=head.biHeight-((float)fmod(y, (float) head.biHeight) + 1);
+ break;
+ default:
+ return;
+ }//switch
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Method return pixel color. Different methods are implemented for out of bounds pixels.
+ * If an image has alpha channel, alpha value is returned in .RGBReserved.
+ *
+ * \param x,y : pixel coordinates
+ * \param ofMethod : out-of-bounds method:
+ * - OF_WRAP - wrap over to pixels on other side of the image
+ * - OF_REPEAT - repeat last pixel on the edge
+ * - OF_COLOR - return input value of color
+ * - OF_BACKGROUND - return background color (if not set, return input color)
+ * - OF_TRANSPARENT - return transparent pixel
+ *
+ * \param rplColor : input color (returned for out-of-bound coordinates in OF_COLOR mode and if other mode is not applicable)
+ *
+ * \return color : color of pixel
+ * \author ***bd*** 2.2004
+ */
+RGBQUAD CxImage::GetPixelColorWithOverflow(int32_t x, int32_t y, OverflowMethod const ofMethod, RGBQUAD* const rplColor)
+{
+ RGBQUAD color; //color to return
+ if ((!IsInside(x,y)) || pDib==NULL) { //is pixel within bouns?:
+ //pixel is out of bounds or no DIB
+ if (rplColor!=NULL)
+ color=*rplColor;
+ else {
+ color.rgbRed=color.rgbGreen=color.rgbBlue=255; color.rgbReserved=0; //default replacement colour: white transparent
+ }//if
+ if (pDib==NULL) return color;
+ //pixel is out of bounds:
+ switch (ofMethod) {
+ case OM_TRANSPARENT:
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) {
+ //alpha transparency is supported and image has alpha layer
+ color.rgbReserved=0;
+ } else {
+#endif //CXIMAGE_SUPPORT_ALPHA
+ //no alpha transparency
+ if (GetTransIndex()>=0) {
+ color=GetTransColor(); //single color transparency enabled (return transparent color)
+ }//if
+#if CXIMAGE_SUPPORT_ALPHA
+ }//if
+#endif //CXIMAGE_SUPPORT_ALPHA
+ return color;
+ case OM_BACKGROUND:
+ //return background color (if it exists, otherwise input value)
+ if (info.nBkgndIndex >= 0) {
+ if (head.biBitCount<24) color = GetPaletteColor((uint8_t)info.nBkgndIndex);
+ else color = info.nBkgndColor;
+ }//if
+ return color;
+ case OM_REPEAT:
+ case OM_WRAP:
+ case OM_MIRROR:
+ OverflowCoordinates(x,y,ofMethod);
+ break;
+ default:
+ //simply return replacement color (OM_COLOR and others)
+ return color;
+ }//switch
+ }//if
+ //just return specified pixel (it's within bounds)
+ return BlindGetPixelColor(x,y);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * This method reconstructs image according to chosen interpolation method and then returns pixel (x,y).
+ * (x,y) can lie between actual image pixels. If (x,y) lies outside of image, method returns value
+ * according to overflow method.
+ * This method is very useful for geometrical image transformations, where destination pixel
+ * can often assume color value lying between source pixels.
+ *
+ * \param (x,y) - coordinates of pixel to return
+ * GPCI method recreates "analogue" image back from digital data, so x and y
+ * are float values and color value of point (1.1,1) will generally not be same
+ * as (1,1). Center of first pixel is at (0,0) and center of pixel right to it is (1,0).
+ * (0.5,0) is half way between these two pixels.
+ * \param inMethod - interpolation (reconstruction) method (kernel) to use:
+ * - IM_NEAREST_NEIGHBOUR - returns colour of nearest lying pixel (causes stairy look of
+ * processed images)
+ * - IM_BILINEAR - interpolates colour from four neighbouring pixels (softens image a bit)
+ * - IM_BICUBIC - interpolates from 16 neighbouring pixels (can produce "halo" artifacts)
+ * - IM_BICUBIC2 - interpolates from 16 neighbouring pixels (perhaps a bit less halo artifacts
+ than IM_BICUBIC)
+ * - IM_BSPLINE - interpolates from 16 neighbouring pixels (softens image, washes colours)
+ * (As far as I know, image should be prefiltered for this method to give
+ * good results... some other time :) )
+ * This method uses bicubic interpolation kernel from CXImage 5.99a and older
+ * versions.
+ * - IM_LANCZOS - interpolates from 12*12 pixels (slow, ringing artifacts)
+ *
+ * \param ofMethod - overflow method (see comments at GetPixelColorWithOverflow)
+ * \param rplColor - pointer to color used for out of borders pixels in OM_COLOR mode
+ * (and other modes if colour can't calculated in a specified way)
+ *
+ * \return interpolated color value (including interpolated alpha value, if image has alpha layer)
+ *
+ * \author ***bd*** 2.2004
+ */
+RGBQUAD CxImage::GetPixelColorInterpolated(
+ float x,float y,
+ InterpolationMethod const inMethod,
+ OverflowMethod const ofMethod,
+ RGBQUAD* const rplColor)
+{
+ //calculate nearest pixel
+ int32_t xi=(int32_t)(x); if (x<0) xi--; //these replace (incredibly slow) floor (Visual c++ 2003, AMD Athlon)
+ int32_t yi=(int32_t)(y); if (y<0) yi--;
+ RGBQUAD color; //calculated colour
+
+ switch (inMethod) {
+ case IM_NEAREST_NEIGHBOUR:
+ return GetPixelColorWithOverflow((int32_t)(x+0.5f), (int32_t)(y+0.5f), ofMethod, rplColor);
+ default: {
+ //IM_BILINEAR: bilinear interpolation
+ if (xi<-1 || xi>=head.biWidth || yi<-1 || yi>=head.biHeight) { //all 4 points are outside bounds?:
+ switch (ofMethod) {
+ case OM_COLOR: case OM_TRANSPARENT: case OM_BACKGROUND:
+ //we don't need to interpolate anything with all points outside in this case
+ return GetPixelColorWithOverflow(-999, -999, ofMethod, rplColor);
+ default:
+ //recalculate coordinates and use faster method later on
+ OverflowCoordinates(x,y,ofMethod);
+ xi=(int32_t)(x); if (x<0) xi--; //x and/or y have changed ... recalculate xi and yi
+ yi=(int32_t)(y); if (y<0) yi--;
+ }//switch
+ }//if
+ //get four neighbouring pixels
+ if ((xi+1)<head.biWidth && xi>=0 && (yi+1)<head.biHeight && yi>=0 && head.biClrUsed==0) {
+ //all pixels are inside RGB24 image... optimize reading (and use fixed point arithmetic)
+ uint16_t wt1=(uint16_t)((x-xi)*256.0f), wt2=(uint16_t)((y-yi)*256.0f);
+ uint16_t wd=wt1*wt2>>8;
+ uint16_t wb=wt1-wd;
+ uint16_t wc=wt2-wd;
+ uint16_t wa=256-wt1-wc;
+ uint16_t wrr,wgg,wbb;
+ uint8_t *pxptr=(uint8_t*)info.pImage+yi*info.dwEffWidth+xi*3;
+ wbb=wa*(*pxptr++); wgg=wa*(*pxptr++); wrr=wa*(*pxptr++);
+ wbb+=wb*(*pxptr++); wgg+=wb*(*pxptr++); wrr+=wb*(*pxptr);
+ pxptr+=(info.dwEffWidth-5); //move to next row
+ wbb+=wc*(*pxptr++); wgg+=wc*(*pxptr++); wrr+=wc*(*pxptr++);
+ wbb+=wd*(*pxptr++); wgg+=wd*(*pxptr++); wrr+=wd*(*pxptr);
+ color.rgbRed=(uint8_t) (wrr>>8); color.rgbGreen=(uint8_t) (wgg>>8); color.rgbBlue=(uint8_t) (wbb>>8);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha) {
+ uint16_t waa;
+ //image has alpha layer... we have to do the same for alpha data
+ pxptr=AlphaGetPointer(xi,yi); //pointer to first byte
+ waa=wa*(*pxptr++); waa+=wb*(*pxptr); //first two pixels
+ pxptr+=(head.biWidth-1); //move to next row
+ waa+=wc*(*pxptr++); waa+=wd*(*pxptr); //and second row pixels
+ color.rgbReserved=(uint8_t) (waa>>8);
+ } else
+#endif
+ { //Alpha not supported or no alpha at all
+ color.rgbReserved = 0;
+ }
+ return color;
+ } else {
+ //default (slower) way to get pixels (not RGB24 or some pixels out of borders)
+ float t1=x-xi, t2=y-yi;
+ float d=t1*t2;
+ float b=t1-d;
+ float c=t2-d;
+ float a=1-t1-c;
+ RGBQUAD rgb11,rgb21,rgb12,rgb22;
+ rgb11=GetPixelColorWithOverflow(xi, yi, ofMethod, rplColor);
+ rgb21=GetPixelColorWithOverflow(xi+1, yi, ofMethod, rplColor);
+ rgb12=GetPixelColorWithOverflow(xi, yi+1, ofMethod, rplColor);
+ rgb22=GetPixelColorWithOverflow(xi+1, yi+1, ofMethod, rplColor);
+ //calculate linear interpolation
+ color.rgbRed=(uint8_t) (a*rgb11.rgbRed+b*rgb21.rgbRed+c*rgb12.rgbRed+d*rgb22.rgbRed);
+ color.rgbGreen=(uint8_t) (a*rgb11.rgbGreen+b*rgb21.rgbGreen+c*rgb12.rgbGreen+d*rgb22.rgbGreen);
+ color.rgbBlue=(uint8_t) (a*rgb11.rgbBlue+b*rgb21.rgbBlue+c*rgb12.rgbBlue+d*rgb22.rgbBlue);
+#if CXIMAGE_SUPPORT_ALPHA
+ color.rgbReserved=(uint8_t) (a*rgb11.rgbReserved+b*rgb21.rgbReserved+c*rgb12.rgbReserved+d*rgb22.rgbReserved);
+#else
+ color.rgbReserved = 0;
+#endif
+ return color;
+ }//if
+ }//default
+ case IM_BICUBIC:
+ case IM_BICUBIC2:
+ case IM_BSPLINE:
+ case IM_BOX:
+ case IM_HERMITE:
+ case IM_HAMMING:
+ case IM_SINC:
+ case IM_BLACKMAN:
+ case IM_BESSEL:
+ case IM_GAUSSIAN:
+ case IM_QUADRATIC:
+ case IM_MITCHELL:
+ case IM_CATROM:
+ case IM_HANNING:
+ case IM_POWER:
+ //bicubic interpolation(s)
+ if (((xi+2)<0) || ((xi-1)>=head.biWidth) || ((yi+2)<0) || ((yi-1)>=head.biHeight)) { //all points are outside bounds?:
+ switch (ofMethod) {
+ case OM_COLOR: case OM_TRANSPARENT: case OM_BACKGROUND:
+ //we don't need to interpolate anything with all points outside in this case
+ return GetPixelColorWithOverflow(-999, -999, ofMethod, rplColor);
+ break;
+ default:
+ //recalculate coordinates and use faster method later on
+ OverflowCoordinates(x,y,ofMethod);
+ xi=(int32_t)(x); if (x<0) xi--; //x and/or y have changed ... recalculate xi and yi
+ yi=(int32_t)(y); if (y<0) yi--;
+ }//switch
+ }//if
+
+ //some variables needed from here on
+ int32_t xii,yii; //x any y integer indexes for loops
+ float kernel, kernelyc; //kernel cache
+ float kernelx[12], kernely[4]; //precalculated kernel values
+ float rr,gg,bb,aa; //accumulated color values
+ //calculate multiplication factors for all pixels
+ int32_t i;
+ switch (inMethod) {
+ case IM_BICUBIC:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelCubic((float)(xi+i-1-x));
+ kernely[i]=KernelCubic((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_BICUBIC2:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelGeneralizedCubic((float)(xi+i-1-x), -0.5);
+ kernely[i]=KernelGeneralizedCubic((float)(yi+i-1-y), -0.5);
+ }//for i
+ break;
+ case IM_BSPLINE:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelBSpline((float)(xi+i-1-x));
+ kernely[i]=KernelBSpline((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_BOX:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelBox((float)(xi+i-1-x));
+ kernely[i]=KernelBox((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_HERMITE:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelHermite((float)(xi+i-1-x));
+ kernely[i]=KernelHermite((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_HAMMING:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelHamming((float)(xi+i-1-x));
+ kernely[i]=KernelHamming((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_SINC:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelSinc((float)(xi+i-1-x));
+ kernely[i]=KernelSinc((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_BLACKMAN:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelBlackman((float)(xi+i-1-x));
+ kernely[i]=KernelBlackman((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_BESSEL:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelBessel((float)(xi+i-1-x));
+ kernely[i]=KernelBessel((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_GAUSSIAN:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelGaussian((float)(xi+i-1-x));
+ kernely[i]=KernelGaussian((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_QUADRATIC:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelQuadratic((float)(xi+i-1-x));
+ kernely[i]=KernelQuadratic((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_MITCHELL:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelMitchell((float)(xi+i-1-x));
+ kernely[i]=KernelMitchell((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_CATROM:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelCatrom((float)(xi+i-1-x));
+ kernely[i]=KernelCatrom((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_HANNING:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelHanning((float)(xi+i-1-x));
+ kernely[i]=KernelHanning((float)(yi+i-1-y));
+ }//for i
+ break;
+ case IM_POWER:
+ for (i=0; i<4; i++) {
+ kernelx[i]=KernelPower((float)(xi+i-1-x));
+ kernely[i]=KernelPower((float)(yi+i-1-y));
+ }//for i
+ break; + default:break;
+ }//switch
+ rr=gg=bb=aa=0;
+ if (((xi+2)<head.biWidth) && xi>=1 && ((yi+2)<head.biHeight) && (yi>=1) && !IsIndexed()) {
+ //optimized interpolation (faster pixel reads) for RGB24 images with all pixels inside bounds
+ for (yii=yi-1; yii<yi+3; yii++) {
+ uint8_t *pxptr=(uint8_t *)BlindGetPixelPointer(xi-1, yii); //calculate pointer to first byte in row
+ kernelyc=kernely[yii-(yi-1)];
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) {
+ //alpha is supported and valid (optimized bicubic int32_t. for image with alpha)
+ uint8_t *pxptra=AlphaGetPointer(xi-1, yii);
+ kernel=kernelyc*kernelx[0];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++); aa+=kernel*(*pxptra++);
+ kernel=kernelyc*kernelx[1];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++); aa+=kernel*(*pxptra++);
+ kernel=kernelyc*kernelx[2];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++); aa+=kernel*(*pxptra++);
+ kernel=kernelyc*kernelx[3];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr); aa+=kernel*(*pxptra);
+ } else
+#endif
+ //alpha not supported or valid (optimized bicubic int32_t. for no alpha channel)
+ {
+ kernel=kernelyc*kernelx[0];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++);
+ kernel=kernelyc*kernelx[1];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++);
+ kernel=kernelyc*kernelx[2];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++);
+ kernel=kernelyc*kernelx[3];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr);
+ }
+ }//yii
+ } else {
+ //slower more flexible interpolation for border pixels and paletted images
+ RGBQUAD rgbs;
+ for (yii=yi-1; yii<yi+3; yii++) {
+ kernelyc=kernely[yii-(yi-1)];
+ for (xii=xi-1; xii<xi+3; xii++) {
+ kernel=kernelyc*kernelx[xii-(xi-1)];
+ rgbs=GetPixelColorWithOverflow(xii, yii, ofMethod, rplColor);
+ rr+=kernel*rgbs.rgbRed;
+ gg+=kernel*rgbs.rgbGreen;
+ bb+=kernel*rgbs.rgbBlue;
+#if CXIMAGE_SUPPORT_ALPHA
+ aa+=kernel*rgbs.rgbReserved;
+#endif
+ }//xii
+ }//yii
+ }//if
+ //for all colors, clip to 0..255 and assign to RGBQUAD
+ if (rr>255) rr=255; if (rr<0) rr=0; color.rgbRed=(uint8_t) rr;
+ if (gg>255) gg=255; if (gg<0) gg=0; color.rgbGreen=(uint8_t) gg;
+ if (bb>255) bb=255; if (bb<0) bb=0; color.rgbBlue=(uint8_t) bb;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (aa>255) aa=255; if (aa<0) aa=0; color.rgbReserved=(uint8_t) aa;
+#else
+ color.rgbReserved = 0;
+#endif
+ return color;
+ case IM_LANCZOS:
+ //lanczos window (16*16) sinc interpolation
+ if (((xi+6)<0) || ((xi-5)>=head.biWidth) || ((yi+6)<0) || ((yi-5)>=head.biHeight)) {
+ //all points are outside bounds
+ switch (ofMethod) {
+ case OM_COLOR: case OM_TRANSPARENT: case OM_BACKGROUND:
+ //we don't need to interpolate anything with all points outside in this case
+ return GetPixelColorWithOverflow(-999, -999, ofMethod, rplColor);
+ break;
+ default:
+ //recalculate coordinates and use faster method later on
+ OverflowCoordinates(x,y,ofMethod);
+ xi=(int32_t)(x); if (x<0) xi--; //x and/or y have changed ... recalculate xi and yi
+ yi=(int32_t)(y); if (y<0) yi--;
+ }//switch
+ }//if
+
+ for (xii=xi-5; xii<xi+7; xii++) kernelx[xii-(xi-5)]=KernelLanczosSinc((float)(xii-x), 6.0f);
+ rr=gg=bb=aa=0;
+
+ if (((xi+6)<head.biWidth) && ((xi-5)>=0) && ((yi+6)<head.biHeight) && ((yi-5)>=0) && !IsIndexed()) {
+ //optimized interpolation (faster pixel reads) for RGB24 images with all pixels inside bounds
+ for (yii=yi-5; yii<yi+7; yii++) {
+ uint8_t *pxptr=(uint8_t *)BlindGetPixelPointer(xi-5, yii); //calculate pointer to first byte in row
+ kernelyc=KernelLanczosSinc((float)(yii-y),6.0f);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) {
+ //alpha is supported and valid
+ uint8_t *pxptra=AlphaGetPointer(xi-1, yii);
+ for (xii=0; xii<12; xii++) {
+ kernel=kernelyc*kernelx[xii];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++); aa+=kernel*(*pxptra++);
+ }//for xii
+ } else
+#endif
+ //alpha not supported or valid
+ {
+ for (xii=0; xii<12; xii++) {
+ kernel=kernelyc*kernelx[xii];
+ bb+=kernel*(*pxptr++); gg+=kernel*(*pxptr++); rr+=kernel*(*pxptr++);
+ }//for xii
+ }
+ }//yii
+ } else {
+ //slower more flexible interpolation for border pixels and paletted images
+ RGBQUAD rgbs;
+ for (yii=yi-5; yii<yi+7; yii++) {
+ kernelyc=KernelLanczosSinc((float)(yii-y),6.0f);
+ for (xii=xi-5; xii<xi+7; xii++) {
+ kernel=kernelyc*kernelx[xii-(xi-5)];
+ rgbs=GetPixelColorWithOverflow(xii, yii, ofMethod, rplColor);
+ rr+=kernel*rgbs.rgbRed;
+ gg+=kernel*rgbs.rgbGreen;
+ bb+=kernel*rgbs.rgbBlue;
+#if CXIMAGE_SUPPORT_ALPHA
+ aa+=kernel*rgbs.rgbReserved;
+#endif
+ }//xii
+ }//yii
+ }//if
+ //for all colors, clip to 0..255 and assign to RGBQUAD
+ if (rr>255) rr=255; if (rr<0) rr=0; color.rgbRed=(uint8_t) rr;
+ if (gg>255) gg=255; if (gg<0) gg=0; color.rgbGreen=(uint8_t) gg;
+ if (bb>255) bb=255; if (bb<0) bb=0; color.rgbBlue=(uint8_t) bb;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (aa>255) aa=255; if (aa<0) aa=0; color.rgbReserved=(uint8_t) aa;
+#else
+ color.rgbReserved = 0;
+#endif
+ return color;
+ }//switch
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Helper function for GetAreaColorInterpolated.
+ * Adds 'surf' portion of image pixel with color 'color' to (rr,gg,bb,aa).
+ */
+void CxImage::AddAveragingCont(RGBQUAD const &color, float const surf, float &rr, float &gg, float &bb, float &aa)
+{
+ rr+=color.rgbRed*surf;
+ gg+=color.rgbGreen*surf;
+ bb+=color.rgbBlue*surf;
+#if CXIMAGE_SUPPORT_ALPHA
+ aa+=color.rgbReserved*surf;
+#endif
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * This method is similar to GetPixelColorInterpolated, but this method also properly handles
+ * subsampling.
+ * If you need to sample original image with interval of more than 1 pixel (as when shrinking an image),
+ * you should use this method instead of GetPixelColorInterpolated or aliasing will occur.
+ * When area width and height are both less than pixel, this method gets pixel color by interpolating
+ * color of frame center with selected (inMethod) interpolation by calling GetPixelColorInterpolated.
+ * If width and height are more than 1, method calculates color by averaging color of pixels within area.
+ * Interpolation method is not used in this case. Pixel color is interpolated by averaging instead.
+ * If only one of both is more than 1, method uses combination of interpolation and averaging.
+ * Chosen interpolation method is used, but since it is averaged later on, there is little difference
+ * between IM_BILINEAR (perhaps best for this case) and better methods. IM_NEAREST_NEIGHBOUR again
+ * leads to aliasing artifacts.
+ * This method is a bit slower than GetPixelColorInterpolated and when aliasing is not a problem, you should
+ * simply use the later.
+ *
+ * \param xc, yc - center of (rectangular) area
+ * \param w, h - width and height of area
+ * \param inMethod - interpolation method that is used, when interpolation is used (see above)
+ * \param ofMethod - overflow method used when retrieving individual pixel colors
+ * \param rplColor - replacement colour to use, in OM_COLOR
+ *
+ * \author ***bd*** 2.2004
+ */
+RGBQUAD CxImage::GetAreaColorInterpolated(
+ float const xc, float const yc, float const w, float const h,
+ InterpolationMethod const inMethod,
+ OverflowMethod const ofMethod,
+ RGBQUAD* const rplColor)
+{
+ RGBQUAD color; //calculated colour
+
+ if (h<=1 && w<=1) {
+ //both width and height are less than one... we will use interpolation of center point
+ return GetPixelColorInterpolated(xc, yc, inMethod, ofMethod, rplColor);
+ } else {
+ //area is wider and/or taller than one pixel:
+ CxRect2 area(xc-w/2.0f, yc-h/2.0f, xc+w/2.0f, yc+h/2.0f); //area
+ int32_t xi1=(int32_t)(area.botLeft.x+0.49999999f); //low x
+ int32_t yi1=(int32_t)(area.botLeft.y+0.49999999f); //low y
+
+
+ int32_t xi2=(int32_t)(area.topRight.x+0.5f); //top x
+ int32_t yi2=(int32_t)(area.topRight.y+0.5f); //top y (for loops)
+
+ float rr,gg,bb,aa; //red, green, blue and alpha components
+ rr=gg=bb=aa=0;
+ int32_t x,y; //loop counters
+ float s=0; //surface of all pixels
+ float cps; //surface of current crosssection
+ if (h>1 && w>1) {
+ //width and height of area are greater than one pixel, so we can employ "ordinary" averaging
+ CxRect2 intBL, intTR; //bottom left and top right intersection
+ intBL=area.CrossSection(CxRect2(((float)xi1)-0.5f, ((float)yi1)-0.5f, ((float)xi1)+0.5f, ((float)yi1)+0.5f));
+ intTR=area.CrossSection(CxRect2(((float)xi2)-0.5f, ((float)yi2)-0.5f, ((float)xi2)+0.5f, ((float)yi2)+0.5f));
+ float wBL, wTR, hBL, hTR;
+ wBL=intBL.Width(); //width of bottom left pixel-area intersection
+ hBL=intBL.Height(); //height of bottom left...
+ wTR=intTR.Width(); //width of top right...
+ hTR=intTR.Height(); //height of top right...
+
+ AddAveragingCont(GetPixelColorWithOverflow(xi1,yi1,ofMethod,rplColor), wBL*hBL, rr, gg, bb, aa); //bottom left pixel
+ AddAveragingCont(GetPixelColorWithOverflow(xi2,yi1,ofMethod,rplColor), wTR*hBL, rr, gg, bb, aa); //bottom right pixel
+ AddAveragingCont(GetPixelColorWithOverflow(xi1,yi2,ofMethod,rplColor), wBL*hTR, rr, gg, bb, aa); //top left pixel
+ AddAveragingCont(GetPixelColorWithOverflow(xi2,yi2,ofMethod,rplColor), wTR*hTR, rr, gg, bb, aa); //top right pixel
+ //bottom and top row
+ for (x=xi1+1; x<xi2; x++) {
+ AddAveragingCont(GetPixelColorWithOverflow(x,yi1,ofMethod,rplColor), hBL, rr, gg, bb, aa); //bottom row
+ AddAveragingCont(GetPixelColorWithOverflow(x,yi2,ofMethod,rplColor), hTR, rr, gg, bb, aa); //top row
+ }
+ //leftmost and rightmost column
+ for (y=yi1+1; y<yi2; y++) {
+ AddAveragingCont(GetPixelColorWithOverflow(xi1,y,ofMethod,rplColor), wBL, rr, gg, bb, aa); //left column
+ AddAveragingCont(GetPixelColorWithOverflow(xi2,y,ofMethod,rplColor), wTR, rr, gg, bb, aa); //right column
+ }
+ for (y=yi1+1; y<yi2; y++) {
+ for (x=xi1+1; x<xi2; x++) {
+ color=GetPixelColorWithOverflow(x,y,ofMethod,rplColor);
+ rr+=color.rgbRed;
+ gg+=color.rgbGreen;
+ bb+=color.rgbBlue;
+#if CXIMAGE_SUPPORT_ALPHA
+ aa+=color.rgbReserved;
+#endif
+ }//for x
+ }//for y
+ } else {
+ //width or height greater than one:
+ CxRect2 intersect; //intersection with current pixel
+ CxPoint2 center;
+ for (y=yi1; y<=yi2; y++) {
+ for (x=xi1; x<=xi2; x++) {
+ intersect=area.CrossSection(CxRect2(((float)x)-0.5f, ((float)y)-0.5f, ((float)x)+0.5f, ((float)y)+0.5f));
+ center=intersect.Center();
+ color=GetPixelColorInterpolated(center.x, center.y, inMethod, ofMethod, rplColor);
+ cps=intersect.Surface();
+ rr+=color.rgbRed*cps;
+ gg+=color.rgbGreen*cps;
+ bb+=color.rgbBlue*cps;
+#if CXIMAGE_SUPPORT_ALPHA
+ aa+=color.rgbReserved*cps;
+#endif
+ }//for x
+ }//for y
+ }//if
+
+ s=area.Surface();
+ rr/=s; gg/=s; bb/=s; aa/=s;
+ if (rr>255) rr=255; if (rr<0) rr=0; color.rgbRed=(uint8_t) rr;
+ if (gg>255) gg=255; if (gg<0) gg=0; color.rgbGreen=(uint8_t) gg;
+ if (bb>255) bb=255; if (bb<0) bb=0; color.rgbBlue=(uint8_t) bb;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (aa>255) aa=255; if (aa<0) aa=0; color.rgbReserved=(uint8_t) aa;
+#else
+ color.rgbReserved = 0;
+#endif
+ }//if
+ return color;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBSpline(const float x)
+{
+ if (x>2.0f) return 0.0f;
+ // thanks to Kristian Kratzenstein
+ float a, b, c, d;
+ float xm1 = x - 1.0f; // Was calculatet anyway cause the "if((x-1.0f) < 0)"
+ float xp1 = x + 1.0f;
+ float xp2 = x + 2.0f;
+
+ if ((xp2) <= 0.0f) a = 0.0f; else a = xp2*xp2*xp2; // Only float, not float -> double -> float
+ if ((xp1) <= 0.0f) b = 0.0f; else b = xp1*xp1*xp1;
+ if (x <= 0) c = 0.0f; else c = x*x*x;
+ if ((xm1) <= 0.0f) d = 0.0f; else d = xm1*xm1*xm1;
+
+ return (0.16666666666666666667f * (a - (4.0f * b) + (6.0f * c) - (4.0f * d)));
+
+ /* equivalent <Vladimír Kloucek>
+ if (x < -2.0)
+ return(0.0f);
+ if (x < -1.0)
+ return((2.0f+x)*(2.0f+x)*(2.0f+x)*0.16666666666666666667f);
+ if (x < 0.0)
+ return((4.0f+x*x*(-6.0f-3.0f*x))*0.16666666666666666667f);
+ if (x < 1.0)
+ return((4.0f+x*x*(-6.0f+3.0f*x))*0.16666666666666666667f);
+ if (x < 2.0)
+ return((2.0f-x)*(2.0f-x)*(2.0f-x)*0.16666666666666666667f);
+ return(0.0f);
+ */
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Bilinear interpolation kernel:
+ \verbatim
+ /
+ | 1-t , if 0 <= t <= 1
+ h(t) = | t+1 , if -1 <= t < 0
+ | 0 , otherwise
+ \
+ \endverbatim
+ * ***bd*** 2.2004
+ */
+float CxImage::KernelLinear(const float t)
+{
+// if (0<=t && t<=1) return 1-t;
+// if (-1<=t && t<0) return 1+t;
+// return 0;
+
+ //<Vladimír Kloucek>
+ if (t < -1.0f)
+ return 0.0f;
+ if (t < 0.0f)
+ return 1.0f+t;
+ if (t < 1.0f)
+ return 1.0f-t;
+ return 0.0f;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Bicubic interpolation kernel (a=-1):
+ \verbatim
+ /
+ | 1-2|t|**2+|t|**3 , if |t| < 1
+ h(t) = | 4-8|t|+5|t|**2-|t|**3 , if 1<=|t|<2
+ | 0 , otherwise
+ \
+ \endverbatim
+ * ***bd*** 2.2004
+ */
+float CxImage::KernelCubic(const float t)
+{
+ float abs_t = (float)fabs(t);
+ float abs_t_sq = abs_t * abs_t;
+ if (abs_t<1) return 1-2*abs_t_sq+abs_t_sq*abs_t;
+ if (abs_t<2) return 4 - 8*abs_t +5*abs_t_sq - abs_t_sq*abs_t;
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Bicubic kernel (for a=-1 it is the same as BicubicKernel):
+ \verbatim
+ /
+ | (a+2)|t|**3 - (a+3)|t|**2 + 1 , |t| <= 1
+ h(t) = | a|t|**3 - 5a|t|**2 + 8a|t| - 4a , 1 < |t| <= 2
+ | 0 , otherwise
+ \
+ \endverbatim
+ * Often used values for a are -1 and -1/2.
+ */
+float CxImage::KernelGeneralizedCubic(const float t, const float a)
+{
+ float abs_t = (float)fabs(t);
+ float abs_t_sq = abs_t * abs_t;
+ if (abs_t<1) return (a+2)*abs_t_sq*abs_t - (a+3)*abs_t_sq + 1;
+ if (abs_t<2) return a*abs_t_sq*abs_t - 5*a*abs_t_sq + 8*a*abs_t - 4*a;
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Lanczos windowed sinc interpolation kernel with radius r.
+ \verbatim
+ /
+ h(t) = | sinc(t)*sinc(t/r) , if |t|<r
+ | 0 , otherwise
+ \
+ \endverbatim
+ * ***bd*** 2.2004
+ */
+float CxImage::KernelLanczosSinc(const float t, const float r)
+{
+ if (fabs(t) > r) return 0;
+ if (t==0) return 1;
+ float pit=PI*t;
+ float pitd=pit/r;
+ return (float)((sin(pit)/pit) * (sin(pitd)/pitd));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBox(const float x)
+{
+ if (x < -0.5f)
+ return 0.0f;
+ if (x < 0.5f)
+ return 1.0f;
+ return 0.0f;
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelHermite(const float x)
+{
+ if (x < -1.0f)
+ return 0.0f;
+ if (x < 0.0f)
+ return (-2.0f*x-3.0f)*x*x+1.0f;
+ if (x < 1.0f)
+ return (2.0f*x-3.0f)*x*x+1.0f;
+ return 0.0f;
+// if (fabs(x)>1) return 0.0f;
+// return(0.5f+0.5f*(float)cos(PI*x));
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelHanning(const float x)
+{
+ if (fabs(x)>1) return 0.0f;
+ return (0.5f+0.5f*(float)cos(PI*x))*((float)sin(PI*x)/(PI*x));
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelHamming(const float x)
+{
+ if (x < -1.0f)
+ return 0.0f;
+ if (x < 0.0f)
+ return 0.92f*(-2.0f*x-3.0f)*x*x+1.0f;
+ if (x < 1.0f)
+ return 0.92f*(2.0f*x-3.0f)*x*x+1.0f;
+ return 0.0f;
+// if (fabs(x)>1) return 0.0f;
+// return(0.54f+0.46f*(float)cos(PI*x));
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelSinc(const float x)
+{
+ if (x == 0.0)
+ return(1.0);
+ return((float)sin(PI*x)/(PI*x));
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBlackman(const float x)
+{
+ //if (fabs(x)>1) return 0.0f;
+ return (0.42f+0.5f*(float)cos(PI*x)+0.08f*(float)cos(2.0f*PI*x));
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBessel_J1(const float x)
+{
+ double p, q;
+
+ register int32_t i;
+
+ static const double
+ Pone[] =
+ {
+ 0.581199354001606143928050809e+21,
+ -0.6672106568924916298020941484e+20,
+ 0.2316433580634002297931815435e+19,
+ -0.3588817569910106050743641413e+17,
+ 0.2908795263834775409737601689e+15,
+ -0.1322983480332126453125473247e+13,
+ 0.3413234182301700539091292655e+10,
+ -0.4695753530642995859767162166e+7,
+ 0.270112271089232341485679099e+4
+ },
+ Qone[] =
+ {
+ 0.11623987080032122878585294e+22,
+ 0.1185770712190320999837113348e+20,
+ 0.6092061398917521746105196863e+17,
+ 0.2081661221307607351240184229e+15,
+ 0.5243710262167649715406728642e+12,
+ 0.1013863514358673989967045588e+10,
+ 0.1501793594998585505921097578e+7,
+ 0.1606931573481487801970916749e+4,
+ 0.1e+1
+ };
+
+ p = Pone[8];
+ q = Qone[8];
+ for (i=7; i >= 0; i--)
+ {
+ p = p*x*x+Pone[i];
+ q = q*x*x+Qone[i];
+ }
+ return (float)(p/q);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBessel_P1(const float x)
+{
+ double p, q;
+
+ register int32_t i;
+
+ static const double
+ Pone[] =
+ {
+ 0.352246649133679798341724373e+5,
+ 0.62758845247161281269005675e+5,
+ 0.313539631109159574238669888e+5,
+ 0.49854832060594338434500455e+4,
+ 0.2111529182853962382105718e+3,
+ 0.12571716929145341558495e+1
+ },
+ Qone[] =
+ {
+ 0.352246649133679798068390431e+5,
+ 0.626943469593560511888833731e+5,
+ 0.312404063819041039923015703e+5,
+ 0.4930396490181088979386097e+4,
+ 0.2030775189134759322293574e+3,
+ 0.1e+1
+ };
+
+ p = Pone[5];
+ q = Qone[5];
+ for (i=4; i >= 0; i--)
+ {
+ p = p*(8.0/x)*(8.0/x)+Pone[i];
+ q = q*(8.0/x)*(8.0/x)+Qone[i];
+ }
+ return (float)(p/q);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBessel_Q1(const float x)
+{
+ double p, q;
+
+ register int32_t i;
+
+ static const double
+ Pone[] =
+ {
+ 0.3511751914303552822533318e+3,
+ 0.7210391804904475039280863e+3,
+ 0.4259873011654442389886993e+3,
+ 0.831898957673850827325226e+2,
+ 0.45681716295512267064405e+1,
+ 0.3532840052740123642735e-1
+ },
+ Qone[] =
+ {
+ 0.74917374171809127714519505e+4,
+ 0.154141773392650970499848051e+5,
+ 0.91522317015169922705904727e+4,
+ 0.18111867005523513506724158e+4,
+ 0.1038187585462133728776636e+3,
+ 0.1e+1
+ };
+
+ p = Pone[5];
+ q = Qone[5];
+ for (i=4; i >= 0; i--)
+ {
+ p = p*(8.0/x)*(8.0/x)+Pone[i];
+ q = q*(8.0/x)*(8.0/x)+Qone[i];
+ }
+ return (float)(p/q);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBessel_Order1(float x)
+{
+ float p, q;
+
+ if (x == 0.0)
+ return (0.0f);
+ p = x;
+ if (x < 0.0)
+ x=(-x);
+ if (x < 8.0)
+ return(p*KernelBessel_J1(x));
+ q = (float)sqrt(2.0f/(PI*x))*(float)(KernelBessel_P1(x)*(1.0f/sqrt(2.0f)*(sin(x)-cos(x)))-8.0f/x*KernelBessel_Q1(x)*
+ (-1.0f/sqrt(2.0f)*(sin(x)+cos(x))));
+ if (p < 0.0f)
+ q = (-q);
+ return (q);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelBessel(const float x)
+{
+ if (x == 0.0f)
+ return(PI/4.0f);
+ return(KernelBessel_Order1(PI*x)/(2.0f*x));
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelGaussian(const float x)
+{
+ return (float)(exp(-2.0f*x*x)*0.79788456080287f/*sqrt(2.0f/PI)*/);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelQuadratic(const float x)
+{
+ if (x < -1.5f)
+ return(0.0f);
+ if (x < -0.5f)
+ return(0.5f*(x+1.5f)*(x+1.5f));
+ if (x < 0.5f)
+ return(0.75f-x*x);
+ if (x < 1.5f)
+ return(0.5f*(x-1.5f)*(x-1.5f));
+ return(0.0f);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelMitchell(const float x)
+{
+#define KM_B (1.0f/3.0f)
+#define KM_C (1.0f/3.0f)
+#define KM_P0 (( 6.0f - 2.0f * KM_B ) / 6.0f)
+#define KM_P2 ((-18.0f + 12.0f * KM_B + 6.0f * KM_C) / 6.0f)
+#define KM_P3 (( 12.0f - 9.0f * KM_B - 6.0f * KM_C) / 6.0f)
+#define KM_Q0 (( 8.0f * KM_B + 24.0f * KM_C) / 6.0f)
+#define KM_Q1 ((-12.0f * KM_B - 48.0f * KM_C) / 6.0f)
+#define KM_Q2 (( 6.0f * KM_B + 30.0f * KM_C) / 6.0f)
+#define KM_Q3 (( -1.0f * KM_B - 6.0f * KM_C) / 6.0f)
+
+ if (x < -2.0)
+ return(0.0f);
+ if (x < -1.0)
+ return(KM_Q0-x*(KM_Q1-x*(KM_Q2-x*KM_Q3)));
+ if (x < 0.0f)
+ return(KM_P0+x*x*(KM_P2-x*KM_P3));
+ if (x < 1.0f)
+ return(KM_P0+x*x*(KM_P2+x*KM_P3));
+ if (x < 2.0f)
+ return(KM_Q0+x*(KM_Q1+x*(KM_Q2+x*KM_Q3)));
+ return(0.0f);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelCatrom(const float x)
+{
+ if (x < -2.0)
+ return(0.0f);
+ if (x < -1.0)
+ return(0.5f*(4.0f+x*(8.0f+x*(5.0f+x))));
+ if (x < 0.0)
+ return(0.5f*(2.0f+x*x*(-5.0f-3.0f*x)));
+ if (x < 1.0)
+ return(0.5f*(2.0f+x*x*(-5.0f+3.0f*x)));
+ if (x < 2.0)
+ return(0.5f*(4.0f+x*(-8.0f+x*(5.0f-x))));
+ return(0.0f);
+}
+////////////////////////////////////////////////////////////////////////////////
+float CxImage::KernelPower(const float x, const float a)
+{
+ if (fabs(x)>1) return 0.0f;
+ return (1.0f - (float)fabs(pow(x,a)));
+}
+////////////////////////////////////////////////////////////////////////////////
+
+#endif
diff --git a/archive/hge/CxImage/ximaiter.h b/archive/hge/CxImage/ximaiter.h new file mode 100644 index 0000000..2371d28 --- /dev/null +++ b/archive/hge/CxImage/ximaiter.h @@ -0,0 +1,253 @@ +/*
+ * File: ImaIter.h
+ * Purpose: Declaration of the Platform Independent Image Base Class
+ * Author: Alejandro Aguilar Sierra
+ * Created: 1995
+ * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
+ *
+ * 07/08/2001 Davide Pizzolato - www.xdp.it
+ * - removed slow loops
+ * - added safe checks
+ *
+ * Permission is given by the author to freely redistribute and include
+ * this code in any program as int32_t as this credit is given where due.
+ *
+ * COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
+ * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
+ * THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
+ * OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
+ * CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
+ * THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
+ * SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
+ * PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
+ * THIS DISCLAIMER.
+ *
+ * Use at your own risk!
+ * ==========================================================
+ */
+
+#if !defined(__ImaIter_h)
+#define __ImaIter_h
+
+#include "ximage.h"
+#include "ximadef.h"
+
+class CImageIterator
+{
+friend class CxImage;
+protected:
+ int32_t Itx, Ity; // Counters
+ int32_t Stepx, Stepy;
+ uint8_t* IterImage; // Image pointer
+ CxImage *ima;
+public:
+ // Constructors
+ CImageIterator ( void );
+ CImageIterator ( CxImage *image );
+ operator CxImage* ();
+
+ // Iterators
+ BOOL ItOK ();
+ void Reset ();
+ void Upset ();
+ void SetRow(uint8_t *buf, int32_t n);
+ void GetRow(uint8_t *buf, int32_t n);
+ uint8_t GetByte( ) { return IterImage[Itx]; }
+ void SetByte(uint8_t b) { IterImage[Itx] = b; }
+ uint8_t* GetRow(void);
+ uint8_t* GetRow(int32_t n);
+ BOOL NextRow();
+ BOOL PrevRow();
+ BOOL NextByte();
+ BOOL PrevByte();
+
+ void SetSteps(int32_t x, int32_t y=0) { Stepx = x; Stepy = y; }
+ void GetSteps(int32_t *x, int32_t *y) { *x = Stepx; *y = Stepy; }
+ BOOL NextStep();
+ BOOL PrevStep();
+
+ void SetY(int32_t y); /* AD - for interlace */
+ int32_t GetY() {return Ity;}
+ BOOL GetCol(uint8_t* pCol, uint32_t x);
+ BOOL SetCol(uint8_t* pCol, uint32_t x);
+};
+
+/////////////////////////////////////////////////////////////////////
+inline
+CImageIterator::CImageIterator(void)
+{
+ ima = 0;
+ IterImage = 0;
+ Itx = Ity = 0;
+ Stepx = Stepy = 0;
+}
+/////////////////////////////////////////////////////////////////////
+inline
+CImageIterator::CImageIterator(CxImage *imageImpl): ima(imageImpl)
+{
+ if (ima) IterImage = ima->GetBits();
+ Itx = Ity = 0;
+ Stepx = Stepy = 0;
+}
+/////////////////////////////////////////////////////////////////////
+inline
+CImageIterator::operator CxImage* ()
+{
+ return ima;
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::ItOK ()
+{
+ if (ima) return ima->IsInside(Itx, Ity);
+ else return FALSE;
+}
+/////////////////////////////////////////////////////////////////////
+inline void CImageIterator::Reset()
+{
+ if (ima) IterImage = ima->GetBits();
+ else IterImage=0;
+ Itx = Ity = 0;
+}
+/////////////////////////////////////////////////////////////////////
+inline void CImageIterator::Upset()
+{
+ Itx = 0;
+ Ity = ima->GetHeight()-1;
+ IterImage = ima->GetBits() + ima->GetEffWidth()*(ima->GetHeight()-1);
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::NextRow()
+{
+ if (++Ity >= (int32_t)ima->GetHeight()) return 0;
+ IterImage += ima->GetEffWidth();
+ return 1;
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::PrevRow()
+{
+ if (--Ity < 0) return 0;
+ IterImage -= ima->GetEffWidth();
+ return 1;
+}
+/* AD - for interlace */
+inline void CImageIterator::SetY(int32_t y)
+{
+ if ((y < 0) || (y > (int32_t)ima->GetHeight())) return;
+ Ity = y;
+ IterImage = ima->GetBits() + ima->GetEffWidth()*y;
+}
+/////////////////////////////////////////////////////////////////////
+inline void CImageIterator::SetRow(uint8_t *buf, int32_t n)
+{
+ if (n<0) n = (int32_t)ima->GetEffWidth();
+ else n = min(n,(int32_t)ima->GetEffWidth());
+
+ if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0)) memcpy(IterImage,buf,n);
+}
+/////////////////////////////////////////////////////////////////////
+inline void CImageIterator::GetRow(uint8_t *buf, int32_t n)
+{
+ if ((IterImage!=NULL)&&(buf!=NULL)&&(n>0))
+ memcpy(buf,IterImage,min(n,(int32_t)ima->GetEffWidth()));
+}
+/////////////////////////////////////////////////////////////////////
+inline uint8_t* CImageIterator::GetRow()
+{
+ return IterImage;
+}
+/////////////////////////////////////////////////////////////////////
+inline uint8_t* CImageIterator::GetRow(int32_t n)
+{
+ SetY(n);
+ return IterImage;
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::NextByte()
+{
+ if (++Itx < (int32_t)ima->GetEffWidth()) return 1;
+ else
+ if (++Ity < (int32_t)ima->GetHeight()){
+ IterImage += ima->GetEffWidth();
+ Itx = 0;
+ return 1;
+ } else
+ return 0;
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::PrevByte()
+{
+ if (--Itx >= 0) return 1;
+ else
+ if (--Ity >= 0){
+ IterImage -= ima->GetEffWidth();
+ Itx = 0;
+ return 1;
+ } else
+ return 0;
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::NextStep()
+{
+ Itx += Stepx;
+ if (Itx < (int32_t)ima->GetEffWidth()) return 1;
+ else {
+ Ity += Stepy;
+ if (Ity < (int32_t)ima->GetHeight()){
+ IterImage += ima->GetEffWidth();
+ Itx = 0;
+ return 1;
+ } else
+ return 0;
+ }
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::PrevStep()
+{
+ Itx -= Stepx;
+ if (Itx >= 0) return 1;
+ else {
+ Ity -= Stepy;
+ if (Ity >= 0 && Ity < (int32_t)ima->GetHeight()) {
+ IterImage -= ima->GetEffWidth();
+ Itx = 0;
+ return 1;
+ } else
+ return 0;
+ }
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::GetCol(uint8_t* pCol, uint32_t x)
+{
+ if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
+ return 0;
+ uint32_t h = ima->GetHeight();
+ //uint32_t line = ima->GetEffWidth();
+ uint8_t bytes = (uint8_t)(ima->GetBpp()>>3);
+ uint8_t* pSrc;
+ for (uint32_t y=0;y<h;y++){
+ pSrc = ima->GetBits(y) + x*bytes;
+ for (uint8_t w=0;w<bytes;w++){
+ *pCol++=*pSrc++;
+ }
+ }
+ return 1;
+}
+/////////////////////////////////////////////////////////////////////
+inline BOOL CImageIterator::SetCol(uint8_t* pCol, uint32_t x)
+{
+ if ((pCol==0)||(ima->GetBpp()<8)||(x>=ima->GetWidth()))
+ return 0;
+ uint32_t h = ima->GetHeight();
+ //uint32_t line = ima->GetEffWidth();
+ uint8_t bytes = (uint8_t)(ima->GetBpp()>>3);
+ uint8_t* pSrc;
+ for (uint32_t y=0;y<h;y++){
+ pSrc = ima->GetBits(y) + x*bytes;
+ for (uint8_t w=0;w<bytes;w++){
+ *pSrc++=*pCol++;
+ }
+ }
+ return 1;
+}
+/////////////////////////////////////////////////////////////////////
+#endif
diff --git a/archive/hge/CxImage/ximajas.cpp b/archive/hge/CxImage/ximajas.cpp new file mode 100644 index 0000000..788e204 --- /dev/null +++ b/archive/hge/CxImage/ximajas.cpp @@ -0,0 +1,325 @@ +/*
+ * File: ximajas.cpp
+ * Purpose: Platform Independent JasPer Image Class Loader and Writer
+ * 12/Apr/2003 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximajas.h"
+
+#if CXIMAGE_SUPPORT_JASPER
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJAS::Decode(CxFile *hFile, uint32_t imagetype)
+{
+ if (hFile == NULL) return false;
+
+ jas_image_t *image=0;
+ jas_stream_t *in=0;
+ jas_matrix_t **bufs=0;
+ int32_t i,error=0;
+ int32_t fmt;
+ //jas_setdbglevel(0);
+
+ cx_try
+ {
+ if (jas_init())
+ cx_throw("cannot initialize jasper");
+
+ in = jas_stream_fdopen(0, "rb");
+ if (!in)
+ cx_throw("error: cannot open standard input");
+
+ CxFileJas src(hFile,in);
+
+ fmt = jas_image_getfmt(in);
+ if (fmt<0)
+ cx_throw("error: unknowm format");
+
+ image = jas_image_decode(in, fmt, 0);
+ if (!image){
+ fmt = -1;
+ cx_throw("error: cannot load image data");
+ }
+
+ char szfmt[4];
+ *szfmt = '\0';
+ strncpy(szfmt,jas_image_fmttostr(fmt),3);
+ szfmt[3] = '\0';
+
+ fmt = -1;
+#if CXIMAGE_SUPPORT_JP2
+ if (strcmp(szfmt,"jp2")==0) fmt = CXIMAGE_FORMAT_JP2;
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ if (strcmp(szfmt,"jpc")==0) fmt = CXIMAGE_FORMAT_JPC;
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ if (strcmp(szfmt,"ras")==0) fmt = CXIMAGE_FORMAT_RAS;
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ if (strcmp(szfmt,"pnm")==0) fmt = CXIMAGE_FORMAT_PNM;
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ if (strcmp(szfmt,"pgx")==0) fmt = CXIMAGE_FORMAT_PGX;
+#endif
+
+ //if (fmt<0)
+ // cx_throw("error: unknowm format");
+
+ int32_t x,y,w,h,depth,cmptno;
+
+ w = jas_image_cmptwidth(image,0);
+ h = jas_image_cmptheight(image,0);
+ depth = jas_image_cmptprec(image,0);
+
+ if (info.nEscape == -1){
+ head.biWidth = w;
+ head.biHeight= h;
+ info.dwType = fmt<0 ? 0 : fmt;
+ cx_throw("output dimensions returned");
+ }
+
+ if (image->numcmpts_ > 64 || image->numcmpts_ < 0)
+ cx_throw("error: too many components");
+
+ // <LD> 01/Jan/2005: Always force conversion to sRGB. Seems to be required for many types of JPEG2000 file.
+ // if (depth!=1 && depth!=4 && depth!=8)
+ if (image->numcmpts_>=3 && depth <=8)
+ {
+ jas_image_t *newimage;
+ jas_cmprof_t *outprof;
+ //jas_eprintf("forcing conversion to sRGB\n");
+ outprof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB);
+ if (!outprof) {
+ cx_throw("cannot create sRGB profile");
+ }
+ newimage = jas_image_chclrspc(image, outprof, JAS_CMXFORM_INTENT_PER);
+ if (!newimage) {
+ jas_cmprof_destroy(outprof); // <LD> 01/Jan/2005: Destroy color profile on error.
+ cx_throw("cannot convert to sRGB");
+ }
+ jas_image_destroy(image);
+ jas_cmprof_destroy(outprof);
+ image = newimage;
+ }
+
+ bufs = (jas_matrix_t **)calloc(image->numcmpts_, sizeof(jas_matrix_t**));
+ for (i = 0; i < image->numcmpts_; ++i) {
+ bufs[i] = jas_matrix_create(1, w);
+ if (!bufs[i]) {
+ cx_throw("error: cannot allocate memory");
+ }
+ }
+
+ int32_t nshift = (depth>8) ? (depth-8) : 0;
+
+ if (image->numcmpts_==3 &&
+ image->cmpts_[0]->width_ == image->cmpts_[1]->width_ &&
+ image->cmpts_[1]->width_ == image->cmpts_[2]->width_ &&
+ image->cmpts_[0]->height_ == image->cmpts_[1]->height_ &&
+ image->cmpts_[1]->height_ == image->cmpts_[2]->height_ &&
+ image->cmpts_[0]->prec_ == image->cmpts_[1]->prec_ &&
+ image->cmpts_[1]->prec_ == image->cmpts_[2]->prec_ )
+ {
+
+ if(!Create(w,h,24,fmt))
+ cx_throw("");
+
+ RGBQUAD c;
+ for (y=0; y<h; y++) {
+ for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) {
+ jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[cmptno]);
+ }
+
+ for (x=0; x<w; x++){
+ c.rgbRed = (uint8_t)((jas_matrix_getv(bufs[0], x)>>nshift));
+ c.rgbGreen = (uint8_t)((jas_matrix_getv(bufs[1], x)>>nshift));
+ c.rgbBlue = (uint8_t)((jas_matrix_getv(bufs[2], x)>>nshift));
+ SetPixelColor(x,h-1-y,c);
+ }
+ }
+ } else {
+ info.nNumFrames = image->numcmpts_;
+ if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){
+ cx_throw("wrong frame!");
+ }
+ for (cmptno=0; cmptno<=info.nFrame; cmptno++) {
+ w = jas_image_cmptwidth(image,cmptno);
+ h = jas_image_cmptheight(image,cmptno);
+ depth = jas_image_cmptprec(image,cmptno);
+ if (depth>8) depth=8;
+ if(!Create(w,h,depth,imagetype))
+ cx_throw("");
+ SetGrayPalette();
+ for (y=0; y<h; y++) {
+ jas_image_readcmpt(image, cmptno, 0, y, w, 1, bufs[0]);
+ for (x=0; x<w; x++){
+ SetPixelIndex(x,h-1-y,(uint8_t)((jas_matrix_getv(bufs[0], x)>>nshift)));
+ }
+ }
+ }
+ }
+
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && fmt>0){
+ error = 0;
+ } else {
+ error = 1;
+ }
+ }
+
+ if (bufs) {
+ for (i = 0; i < image->numcmpts_; ++i){ if (bufs[i]) jas_matrix_destroy(bufs[i]);}
+ free(bufs);
+ }
+ jas_cleanup();
+ if (image) jas_image_destroy(image);
+ if (in) jas_stream_close(in);
+ return (error==0);
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJAS::Encode(CxFile * hFile, uint32_t imagetype)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ if (head.biClrUsed!=0 && !IsGrayScale()){
+ strcpy(info.szLastError,"JasPer can save only RGB or GrayScale images");
+ return false;
+ }
+
+ jas_image_t *image=0;
+ jas_stream_t *out=0;
+ jas_matrix_t *cmpts[3];
+ int32_t x,y,yflip,error=0;
+ uint_fast16_t cmptno, numcmpts=0;
+ jas_image_cmptparm_t cmptparms[3], *cmptparm;
+
+ cx_try {
+
+ if (jas_init())
+ cx_throw("cannot initialize jasper");
+
+ out = jas_stream_fdopen(0, "wb");
+ if (!out)
+ cx_throw("error: cannot open standard output");
+
+ CxFileJas src(hFile,out);
+
+ numcmpts = head.biClrUsed==0 ? 3 : 1;
+
+ for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, ++cmptparm) {
+ cmptparm->tlx = 0;
+ cmptparm->tly = 0;
+ cmptparm->hstep = 1;
+ cmptparm->vstep = 1;
+ cmptparm->width = head.biWidth;
+ cmptparm->height = head.biHeight;
+ cmptparm->prec = 8;
+ cmptparm->sgnd = false;
+ }
+
+ /* Create image object. */
+ image = jas_image_create(numcmpts, cmptparms, JAS_CLRSPC_UNKNOWN);
+ if (!image)
+ cx_throw("error : jas_image_create");
+
+ if (numcmpts == 3) {
+ jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
+ jas_image_setcmpttype(image, 0,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
+ jas_image_setcmpttype(image, 1,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
+ jas_image_setcmpttype(image, 2,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
+ } else {
+ jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
+ jas_image_setcmpttype(image, 0,
+ JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
+ }
+
+
+ for (x = 0; x < numcmpts; ++x) { cmpts[x] = 0; }
+ /* Create temporary matrices to hold component data. */
+ for (x = 0; x < numcmpts; ++x) {
+ cmpts[x] = jas_matrix_create(1, head.biWidth);
+ if (!cmpts[x]) {
+ cx_throw("error : can't allocate memory");
+ }
+ }
+
+ RGBQUAD c;
+ for (y = 0; y < head.biHeight; ++y) {
+ for (x = 0; x < head.biWidth; ++x) {
+ if (head.biClrUsed==0){
+ c = GetPixelColor(x,y);
+ jas_matrix_setv(cmpts[0], x, c.rgbRed);
+ jas_matrix_setv(cmpts[1], x, c.rgbGreen);
+ jas_matrix_setv(cmpts[2], x, c.rgbBlue);
+ } else {
+ jas_matrix_setv(cmpts[0], x, GetPixelIndex(x,y));
+ }
+ }
+ yflip = head.biHeight - 1 - y;
+ for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
+ if (jas_image_writecmpt(image, cmptno, 0, yflip, head.biWidth, 1, cmpts[cmptno])) {
+ cx_throw("error : jas_image_writecmpt");
+ }
+ }
+ }
+
+ char szfmt[4];
+ *szfmt = '\0';
+#if CXIMAGE_SUPPORT_JP2
+ if (imagetype == CXIMAGE_FORMAT_JP2) strcpy(szfmt,"jp2");
+#endif
+#if CXIMAGE_SUPPORT_JPC
+ if (imagetype == CXIMAGE_FORMAT_JPC) strcpy(szfmt,"jpc");
+#endif
+#if CXIMAGE_SUPPORT_RAS
+ if (imagetype == CXIMAGE_FORMAT_RAS) strcpy(szfmt,"ras");
+#endif
+#if CXIMAGE_SUPPORT_PNM
+ if (imagetype == CXIMAGE_FORMAT_PNM) strcpy(szfmt,"pnm");
+#endif
+#if CXIMAGE_SUPPORT_PGX
+ if (imagetype == CXIMAGE_FORMAT_PGX){
+ strcpy(szfmt,"pgx");
+ if (head.biClrUsed==0) cx_throw("PGX can save only GrayScale images");
+ }
+#endif
+ int32_t outfmt = jas_image_strtofmt(szfmt);
+
+ char szoutopts[32];
+ sprintf(szoutopts,"rate=%.3f", info.fQuality/100.0f);
+
+ if (jas_image_encode(image, out, outfmt, szoutopts)) {
+ cx_throw("error: cannot encode image");
+ }
+ jas_stream_flush(out);
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ error = 1;
+ }
+
+ for (x = 0; x < numcmpts; ++x) { if (cmpts[x]) { jas_matrix_destroy(cmpts[x]); } }
+ jas_cleanup();
+ if (image) jas_image_destroy(image);
+ if (out) jas_stream_close(out);
+
+ return (error==0);
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_JASPER
+
diff --git a/archive/hge/CxImage/ximajas.h b/archive/hge/CxImage/ximajas.h new file mode 100644 index 0000000..da76dfc --- /dev/null +++ b/archive/hge/CxImage/ximajas.h @@ -0,0 +1,88 @@ +/*
+ * File: ximajas.h
+ * Purpose: Jasper Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageJAS (c) 12/Apr/2003 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * based on JasPer Copyright (c) 2001-2003 Michael David Adams - All rights reserved.
+ * ==========================================================
+ */
+#if !defined(__ximaJAS_h)
+#define __ximaJAS_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_JASPER
+
+#ifdef _LINUX
+ #include <jasper/jasper.h>
+#else
+ #include "../jasper/include/jasper/jasper.h"
+#endif
+
+class CxImageJAS: public CxImage
+{
+public:
+ CxImageJAS(): CxImage((uint32_t)0) {} // <vho> cast to uint32_t
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,0);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,0);}
+ bool Decode(CxFile * hFile, uint32_t imagetype = 0);
+ bool Decode(FILE *hFile, uint32_t imagetype = 0) { CxIOFile file(hFile); return Decode(&file,imagetype); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile, uint32_t imagetype = 0);
+ bool Encode(FILE *hFile, uint32_t imagetype = 0) { CxIOFile file(hFile); return Encode(&file,imagetype); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+protected:
+
+ class CxFileJas
+ {
+ public:
+ CxFileJas(CxFile* pFile,jas_stream_t *stream)
+ {
+ if (stream->obj_) jas_free(stream->obj_);
+ stream->obj_ = pFile;
+
+ // <vho> - cannot set the stream->ops_->functions here,
+ // because this overwrites a static structure in the Jasper library.
+ // This structure is used by Jasper for internal operations too, e.g. tempfile.
+ // However the ops_ pointer in the stream can be overwritten.
+
+ //stream->ops_->close_ = JasClose;
+ //stream->ops_->read_ = JasRead;
+ //stream->ops_->seek_ = JasSeek;
+ //stream->ops_->write_ = JasWrite;
+
+ jas_stream_CxFile.close_ = JasClose;
+ jas_stream_CxFile.read_ = JasRead;
+ jas_stream_CxFile.seek_ = JasSeek;
+ jas_stream_CxFile.write_ = JasWrite;
+
+ stream->ops_ = &jas_stream_CxFile;
+
+ // <vho> - end
+ }
+ static int32_t JasRead(jas_stream_obj_t *obj, char *buf, int32_t cnt)
+ { return ((CxFile*)obj)->Read(buf,1,cnt); }
+ static int32_t JasWrite(jas_stream_obj_t *obj, char *buf, int32_t cnt)
+ { return ((CxFile*)obj)->Write(buf,1,cnt); }
+ static long JasSeek(jas_stream_obj_t *obj, long offset, int32_t origin)
+ { return ((CxFile*)obj)->Seek(offset,origin); }
+ static int32_t JasClose(jas_stream_obj_t * /*obj*/)
+ { return 1; }
+
+ // <vho>
+private:
+ jas_stream_ops_t jas_stream_CxFile;
+ // <vho> - end
+
+ };
+
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximajbg.cpp b/archive/hge/CxImage/ximajbg.cpp new file mode 100644 index 0000000..ee7bc10 --- /dev/null +++ b/archive/hge/CxImage/ximajbg.cpp @@ -0,0 +1,174 @@ +/*
+ * File: ximajbg.cpp
+ * Purpose: Platform Independent JBG Image Class Loader and Writer
+ * 18/Aug/2002 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximajbg.h"
+
+#if CXIMAGE_SUPPORT_JBG
+
+#include "ximaiter.h"
+
+#define JBIG_BUFSIZE 8192
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJBG::Decode(CxFile *hFile)
+{
+ if (hFile == NULL) return false;
+
+ struct jbg_dec_state jbig_state;
+ uint32_t xmax = 4294967295UL, ymax = 4294967295UL;
+ uint32_t len, cnt;
+ uint8_t *buffer=0,*p;
+ int32_t result;
+
+ cx_try
+ {
+ jbg_dec_init(&jbig_state);
+ jbg_dec_maxsize(&jbig_state, xmax, ymax);
+
+ buffer = (uint8_t*)malloc(JBIG_BUFSIZE);
+ if (!buffer) cx_throw("Sorry, not enough memory available!");
+
+ result = JBG_EAGAIN;
+ do {
+ len = hFile->Read(buffer, 1, JBIG_BUFSIZE);
+ if (!len) break;
+ cnt = 0;
+ p = buffer;
+ while (len > 0 && (result == JBG_EAGAIN || result == JBG_EOK)) {
+ result = jbg_dec_in(&jbig_state, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ }
+ } while (result == JBG_EAGAIN || result == JBG_EOK);
+
+ if (hFile->Error())
+ cx_throw("Problem while reading input file");
+ if (result != JBG_EOK && result != JBG_EOK_INTR)
+ cx_throw("Problem with input file");
+
+ int32_t w, h, bpp, planes, ew;
+
+ w = jbg_dec_getwidth(&jbig_state);
+ h = jbg_dec_getheight(&jbig_state);
+ planes = jbg_dec_getplanes(&jbig_state);
+ bpp = (planes+7)>>3;
+ ew = (w + 7)>>3;
+
+ if (info.nEscape == -1){
+ head.biWidth = w;
+ head.biHeight= h;
+ info.dwType = CXIMAGE_FORMAT_JBG;
+ cx_throw("output dimensions returned");
+ }
+
+ switch (planes){
+ case 1:
+ {
+ uint8_t* binary_image = jbg_dec_getimage(&jbig_state, 0);
+
+ if (!Create(w,h,1,CXIMAGE_FORMAT_JBG))
+ cx_throw("");
+
+ SetPaletteColor(0,255,255,255);
+ SetPaletteColor(1,0,0,0);
+
+ CImageIterator iter(this);
+ iter.Upset();
+ for (int32_t i=0;i<h;i++){
+ iter.SetRow(binary_image+i*ew,ew);
+ iter.PrevRow();
+ }
+
+ break;
+ }
+ default:
+ cx_throw("cannot decode images with more than 1 plane");
+ }
+
+ jbg_dec_free(&jbig_state);
+ free(buffer);
+
+ } cx_catch {
+ jbg_dec_free(&jbig_state);
+ if (buffer) free(buffer);
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_JBG) return true;
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJBG::Encode(CxFile * hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ if (head.biBitCount != 1){
+ strcpy(info.szLastError,"JBG can save only 1-bpp images");
+ return false;
+ }
+
+ int32_t w, h, bpp, planes, ew, i, j, x, y;
+
+ w = head.biWidth;
+ h = head.biHeight;
+ planes = 1;
+ bpp = (planes+7)>>3;
+ ew = (w + 7)>>3;
+
+ uint8_t mask;
+ RGBQUAD *rgb = GetPalette();
+ if (CompareColors(&rgb[0],&rgb[1])<0) mask=255; else mask=0;
+
+ uint8_t *buffer = (uint8_t*)malloc(ew*h*2);
+ if (!buffer) {
+ strcpy(info.szLastError,"Sorry, not enough memory available!");
+ return false;
+ }
+
+ for (y=0; y<h; y++){
+ i= y*ew;
+ j= (h-y-1)*info.dwEffWidth;
+ for (x=0; x<ew; x++){
+ buffer[i + x]=info.pImage[j + x]^mask;
+ }
+ }
+
+ struct jbg_enc_state jbig_state;
+ jbg_enc_init(&jbig_state, w, h, planes, &buffer, jbig_data_out, hFile);
+
+ //jbg_enc_layers(&jbig_state, 2);
+ //jbg_enc_lrlmax(&jbig_state, 800, 600);
+
+ // Specify a few other options (each is ignored if negative)
+ int32_t dl = -1, dh = -1, d = -1, l0 = -1, mx = -1;
+ int32_t options = JBG_TPDON | JBG_TPBON | JBG_DPON;
+ int32_t order = JBG_ILEAVE | JBG_SMID;
+ jbg_enc_lrange(&jbig_state, dl, dh);
+ jbg_enc_options(&jbig_state, order, options, l0, mx, -1);
+
+ // now encode everything and send it to data_out()
+ jbg_enc_out(&jbig_state);
+
+ // give encoder a chance to free its temporary data structures
+ jbg_enc_free(&jbig_state);
+
+ free(buffer);
+
+ if (hFile->Error()){
+ strcpy(info.szLastError,"Problem while writing JBG file");
+ return false;
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_JBG
+
diff --git a/archive/hge/CxImage/ximajbg.h b/archive/hge/CxImage/ximajbg.h new file mode 100644 index 0000000..1cf4965 --- /dev/null +++ b/archive/hge/CxImage/ximajbg.h @@ -0,0 +1,44 @@ +/*
+ * File: ximajbg.h
+ * Purpose: JBG Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageJBG (c) 18/Aug/2002 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * based on LIBJBG Copyright (c) 2002, Markus Kuhn - All rights reserved.
+ * ==========================================================
+ */
+#if !defined(__ximaJBG_h)
+#define __ximaJBG_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_JBG
+
+extern "C" {
+#include "../jbig/jbig.h"
+};
+
+class CxImageJBG: public CxImage
+{
+public:
+ CxImageJBG(): CxImage(CXIMAGE_FORMAT_JBG) {}
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JBG);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JBG);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+protected:
+ static void jbig_data_out(uint8_t *buffer, uint32_t len, void *file)
+ {((CxFile*)file)->Write(buffer,len,1);}
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximajpg.cpp b/archive/hge/CxImage/ximajpg.cpp new file mode 100644 index 0000000..b66bf97 --- /dev/null +++ b/archive/hge/CxImage/ximajpg.cpp @@ -0,0 +1,538 @@ +/*
+ * File: ximajpg.cpp
+ * Purpose: Platform Independent JPEG Image Class Loader and Writer
+ * 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximajpg.h"
+
+#if CXIMAGE_SUPPORT_JPG
+
+#ifdef _LINUX
+ #include <jmorecfg.h>
+#else
+ #include "../jpeg/jmorecfg.h"
+#endif
+
+#include "ximaiter.h"
+
+#include <setjmp.h>
+
+struct jpg_error_mgr {
+ struct jpeg_error_mgr pub; /* "public" fields */
+ jmp_buf setjmp_buffer; /* for return to caller */
+ char* buffer; /* error message <CSC>*/
+};
+typedef jpg_error_mgr *jpg_error_ptr;
+
+////////////////////////////////////////////////////////////////////////////////
+// Here's the routine that will replace the standard error_exit method:
+////////////////////////////////////////////////////////////////////////////////
+static void
+ima_jpeg_error_exit (j_common_ptr cinfo)
+{
+ /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+ jpg_error_ptr myerr = (jpg_error_ptr) cinfo->err;
+ /* Create the message */
+ myerr->pub.format_message (cinfo, myerr->buffer);
+ /* Send it to stderr, adding a newline */
+ /* Return control to the setjmp point */
+ longjmp(myerr->setjmp_buffer, 1);
+}
+////////////////////////////////////////////////////////////////////////////////
+CxImageJPG::CxImageJPG(): CxImage(CXIMAGE_FORMAT_JPG)
+{
+#if CXIMAGEJPG_SUPPORT_EXIF
+ m_exif = NULL;
+ memset(&info.ExifInfo, 0, sizeof(EXIFINFO));
+#endif
+}
+////////////////////////////////////////////////////////////////////////////////
+CxImageJPG::~CxImageJPG()
+{
+#if CXIMAGEJPG_SUPPORT_EXIF
+ if (m_exif) delete m_exif;
+#endif
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGEJPG_SUPPORT_EXIF
+bool CxImageJPG::DecodeExif(CxFile * hFile)
+{
+ m_exif = new CxExifInfo(&info.ExifInfo);
+ if (m_exif){
+ int32_t pos=hFile->Tell();
+ m_exif->DecodeExif(hFile);
+ hFile->Seek(pos,SEEK_SET);
+ return m_exif->m_exifinfo->IsExif;
+ } else {
+ return false;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJPG::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
+{
+ CxIOFile file;
+ if (!file.Open(filename, _T("rb"))) return false;
+ CxExifInfo exif(&info.ExifInfo);
+ exif.DecodeExif(&file);
+ if (info.ExifInfo.IsExif && info.ExifInfo.ThumbnailPointer && info.ExifInfo.ThumbnailSize > 0)
+ { // have a thumbnail - check whether it needs rotating or resizing
+ // TODO: Write a fast routine to read the jpeg header to get the width and height
+ CxImage image(info.ExifInfo.ThumbnailPointer, info.ExifInfo.ThumbnailSize, CXIMAGE_FORMAT_JPG);
+ if (image.IsValid())
+ {
+ if (image.GetWidth() > 256 || image.GetHeight() > 256)
+ { // resize the image
+// float amount = 256.0f / max(image.GetWidth(), image.GetHeight());
+// image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0);
+ }
+ if (info.ExifInfo.Orientation != 1)
+ image.RotateExif(info.ExifInfo.Orientation);
+ return image.Save(outname, CXIMAGE_FORMAT_JPG);
+ }
+ // nice and fast, but we can't resize :(
+ /*
+ FILE *hFileWrite;
+ if ((hFileWrite=fopen(outname, "wb")) != NULL)
+ {
+ fwrite(m_exifinfo.ThumbnailPointer, m_exifinfo.ThumbnailSize, 1, hFileWrite);
+ fclose(hFileWrite);
+ return true;
+ }*/
+ }
+ return false;
+}
+#endif //CXIMAGEJPG_SUPPORT_EXIF
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJPG::Decode(CxFile * hFile)
+{
+
+ bool is_exif = false;
+#if CXIMAGEJPG_SUPPORT_EXIF
+ is_exif = DecodeExif(hFile);
+#endif
+
+ CImageIterator iter(this);
+ /* This struct contains the JPEG decompression parameters and pointers to
+ * working space (which is allocated as needed by the JPEG library).
+ */
+ struct jpeg_decompress_struct cinfo;
+ /* We use our private extension JPEG error handler. <CSC> */
+ struct jpg_error_mgr jerr;
+ jerr.buffer=info.szLastError;
+ /* More stuff */
+ JSAMPARRAY buffer; /* Output row buffer */
+ int32_t row_stride; /* physical row width in output buffer */
+
+ /* In this example we want to open the input file before doing anything else,
+ * so that the setjmp() error recovery below can assume the file is open.
+ * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
+ * requires it in order to read binary files.
+ */
+
+ /* Step 1: allocate and initialize JPEG decompression object */
+ /* We set up the normal JPEG error routines, then override error_exit. */
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = ima_jpeg_error_exit;
+
+ CxFileJpg src(hFile);
+
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(&cinfo);
+ return 0;
+ }
+ /* Now we can initialize the JPEG decompression object. */
+ jpeg_create_decompress(&cinfo);
+
+ /* Step 2: specify data source (eg, a file) */
+ //jpeg_stdio_src(&cinfo, infile);
+ cinfo.src = &src;
+
+ /* Step 3: read file parameters with jpeg_read_header() */
+ (void) jpeg_read_header(&cinfo, TRUE);
+
+ /* Step 4 <chupeev> handle decoder options*/
+ uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114]
+ if ((dwCodecOptions & DECODE_GRAYSCALE) != 0)
+ cinfo.out_color_space = JCS_GRAYSCALE;
+ if ((dwCodecOptions & DECODE_QUANTIZE) != 0) {
+ cinfo.quantize_colors = TRUE;
+ cinfo.desired_number_of_colors = GetJpegQuality();
+ }
+ if ((dwCodecOptions & DECODE_DITHER) != 0)
+ cinfo.dither_mode = m_nDither;
+ if ((dwCodecOptions & DECODE_ONEPASS) != 0)
+ cinfo.two_pass_quantize = FALSE;
+ if ((dwCodecOptions & DECODE_NOSMOOTH) != 0)
+ cinfo.do_fancy_upsampling = FALSE;
+
+//<DP>: Load true color images as RGB (no quantize)
+/* Step 4: set parameters for decompression */
+/* if (cinfo.jpeg_color_space!=JCS_GRAYSCALE) {
+ * cinfo.quantize_colors = TRUE;
+ * cinfo.desired_number_of_colors = 128;
+ *}
+ */ //</DP>
+
+ cinfo.scale_num = 1;
+ // Set the scale <ignacio>
+ cinfo.scale_denom = GetJpegScale();
+
+ // Borrowed the idea from GIF implementation <ignacio>
+ if (info.nEscape == -1) {
+ // Return output dimensions only
+ jpeg_calc_output_dimensions(&cinfo);
+ head.biWidth = cinfo.output_width;
+ head.biHeight = cinfo.output_height;
+ info.dwType = CXIMAGE_FORMAT_JPG;
+ jpeg_destroy_decompress(&cinfo);
+ return true;
+ }
+
+ /* Step 5: Start decompressor */
+ jpeg_start_decompress(&cinfo);
+
+ /* We may need to do some setup of our own at this point before reading
+ * the data. After jpeg_start_decompress() we have the correct scaled
+ * output image dimensions available, as well as the output colormap
+ * if we asked for color quantization.
+ */
+ //Create the image using output dimensions <ignacio>
+ //Create(cinfo.image_width, cinfo.image_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
+ Create(cinfo.output_width, cinfo.output_height, 8*cinfo.output_components, CXIMAGE_FORMAT_JPG);
+
+ if (!pDib) longjmp(jerr.setjmp_buffer, 1); //<DP> check if the image has been created
+
+ if (is_exif){
+#if CXIMAGEJPG_SUPPORT_EXIF
+ if ((info.ExifInfo.Xresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0))
+ SetXDPI((int32_t)(info.ExifInfo.Xresolution/info.ExifInfo.ResolutionUnit));
+ if ((info.ExifInfo.Yresolution != 0.0) && (info.ExifInfo.ResolutionUnit != 0))
+ SetYDPI((int32_t)(info.ExifInfo.Yresolution/info.ExifInfo.ResolutionUnit));
+#endif
+ } else {
+ switch (cinfo.density_unit) {
+ case 0: // [andy] fix for aspect ratio...
+ if((cinfo.Y_density > 0) && (cinfo.X_density > 0)){
+ SetYDPI((int32_t)(GetXDPI()*(float(cinfo.Y_density)/float(cinfo.X_density))));
+ }
+ break;
+ case 2: // [andy] fix: cinfo.X/Y_density is pixels per centimeter
+ SetXDPI((int32_t)floor(cinfo.X_density * 2.54 + 0.5));
+ SetYDPI((int32_t)floor(cinfo.Y_density * 2.54 + 0.5));
+ break;
+ default:
+ SetXDPI(cinfo.X_density);
+ SetYDPI(cinfo.Y_density);
+ }
+ }
+
+ if (cinfo.out_color_space==JCS_GRAYSCALE){
+ SetGrayPalette();
+ head.biClrUsed =256;
+ } else {
+ if (cinfo.quantize_colors){
+ SetPalette(cinfo.actual_number_of_colors, cinfo.colormap[0], cinfo.colormap[1], cinfo.colormap[2]);
+ head.biClrUsed=cinfo.actual_number_of_colors;
+ } else {
+ head.biClrUsed=0;
+ }
+ }
+
+ /* JSAMPLEs per row in output buffer */
+ row_stride = cinfo.output_width * cinfo.output_components;
+
+ /* Make a one-row-high sample array that will go away when done with image */
+ buffer = (*cinfo.mem->alloc_sarray)
+ ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
+
+ /* Step 6: while (scan lines remain to be read) */
+ /* jpeg_read_scanlines(...); */
+ /* Here we use the library's state variable cinfo.output_scanline as the
+ * loop counter, so that we don't have to keep track ourselves.
+ */
+ iter.Upset();
+ while (cinfo.output_scanline < cinfo.output_height) {
+
+ if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
+
+ (void) jpeg_read_scanlines(&cinfo, buffer, 1);
+ // info.nProgress = (int32_t)(100*cinfo.output_scanline/cinfo.output_height);
+ //<DP> Step 6a: CMYK->RGB */
+ if ((cinfo.num_components==4)&&(cinfo.quantize_colors==FALSE)){
+ uint8_t k,*dst,*src;
+ dst=iter.GetRow();
+ src=buffer[0];
+ for(int32_t x3=0,x4=0; x3<(int32_t)info.dwEffWidth && x4<row_stride; x3+=3, x4+=4){
+ k=src[x4+3];
+ dst[x3] =(uint8_t)((k * src[x4+2])/255);
+ dst[x3+1]=(uint8_t)((k * src[x4+1])/255);
+ dst[x3+2]=(uint8_t)((k * src[x4+0])/255);
+ }
+ } else {
+ /* Assume put_scanline_someplace wants a pointer and sample count. */
+ iter.SetRow(buffer[0], row_stride);
+ }
+ iter.PrevRow();
+ }
+
+ /* Step 7: Finish decompression */
+ (void) jpeg_finish_decompress(&cinfo);
+ /* We can ignore the return value since suspension is not possible
+ * with the stdio data source.
+ */
+
+ //<DP> Step 7A: Swap red and blue components
+ // not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
+ if ((cinfo.num_components==3)&&(cinfo.quantize_colors==FALSE)){
+ uint8_t* r0=GetBits();
+ for(int32_t y=0;y<head.biHeight;y++){
+ if (info.nEscape) longjmp(jerr.setjmp_buffer, 1); // <vho> - cancel decoding
+ RGBtoBGR(r0,3*head.biWidth);
+ r0+=info.dwEffWidth;
+ }
+ }
+
+ /* Step 8: Release JPEG decompression object */
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_decompress(&cinfo);
+
+ /* At this point you may want to check to see whether any corrupt-data
+ * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
+ */
+
+ /* And we're done! */
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageJPG::Encode(CxFile * hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ if (head.biClrUsed!=0 && !IsGrayScale()){
+ strcpy(info.szLastError,"JPEG can save only RGB or GreyScale images");
+ return false;
+ }
+
+ // necessary for EXIF, and for roll backs
+ int32_t pos=hFile->Tell();
+
+ /* This struct contains the JPEG compression parameters and pointers to
+ * working space (which is allocated as needed by the JPEG library).
+ * It is possible to have several such structures, representing multiple
+ * compression/decompression processes, in existence at once. We refer
+ * to any one struct (and its associated working data) as a "JPEG object".
+ */
+ struct jpeg_compress_struct cinfo;
+ /* This struct represents a JPEG error handler. It is declared separately
+ * because applications often want to supply a specialized error handler
+ * (see the second half of this file for an example). But here we just
+ * take the easy way out and use the standard error handler, which will
+ * print a message on stderr and call exit() if compression fails.
+ * Note that this struct must live as int32_t as the main JPEG parameter
+ * struct, to avoid dangling-pointer problems.
+ */
+ //struct jpeg_error_mgr jerr;
+ /* We use our private extension JPEG error handler. <CSC> */
+ struct jpg_error_mgr jerr;
+ jerr.buffer=info.szLastError;
+ /* More stuff */
+ int32_t row_stride; /* physical row width in image buffer */
+ JSAMPARRAY buffer; /* Output row buffer */
+
+ /* Step 1: allocate and initialize JPEG compression object */
+ /* We have to set up the error handler first, in case the initialization
+ * step fails. (Unlikely, but it could happen if you are out of memory.)
+ * This routine fills in the contents of struct jerr, and returns jerr's
+ * address which we place into the link field in cinfo.
+ */
+ //cinfo.err = jpeg_std_error(&jerr); <CSC>
+ /* We set up the normal JPEG error routines, then override error_exit. */
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = ima_jpeg_error_exit;
+
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ strcpy(info.szLastError, jerr.buffer); //<CSC>
+ jpeg_destroy_compress(&cinfo);
+ return 0;
+ }
+
+ /* Now we can initialize the JPEG compression object. */
+ jpeg_create_compress(&cinfo);
+ /* Step 2: specify data destination (eg, a file) */
+ /* Note: steps 2 and 3 can be done in either order. */
+ /* Here we use the library-supplied code to send compressed data to a
+ * stdio stream. You can also write your own code to do something else.
+ * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
+ * requires it in order to write binary files.
+ */
+
+ //jpeg_stdio_dest(&cinfo, outfile);
+ CxFileJpg dest(hFile);
+ cinfo.dest = &dest;
+
+ /* Step 3: set parameters for compression */
+ /* First we supply a description of the input image.
+ * Four fields of the cinfo struct must be filled in:
+ */
+ cinfo.image_width = GetWidth(); // image width and height, in pixels
+ cinfo.image_height = GetHeight();
+
+ if (IsGrayScale()){
+ cinfo.input_components = 1; // # of color components per pixel
+ cinfo.in_color_space = JCS_GRAYSCALE; /* colorspace of input image */
+ } else {
+ cinfo.input_components = 3; // # of color components per pixel
+ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+ }
+
+ /* Now use the library's routine to set default compression parameters.
+ * (You must set at least cinfo.in_color_space before calling this,
+ * since the defaults depend on the source color space.)
+ */
+ jpeg_set_defaults(&cinfo);
+ /* Now you can set any non-default parameters you wish to.
+ * Here we just illustrate the use of quality (quantization table) scaling:
+ */
+
+ uint32_t dwCodecOptions = GetCodecOption(CXIMAGE_FORMAT_JPG); //[nm_114]
+//#ifdef C_ARITH_CODING_SUPPORTED
+ if ((dwCodecOptions & ENCODE_ARITHMETIC) != 0)
+ cinfo.arith_code = TRUE;
+//#endif
+
+//#ifdef ENTROPY_OPT_SUPPORTED
+ if ((dwCodecOptions & ENCODE_OPTIMIZE) != 0)
+ cinfo.optimize_coding = TRUE;
+//#endif
+
+ if ((dwCodecOptions & ENCODE_GRAYSCALE) != 0)
+ jpeg_set_colorspace(&cinfo, JCS_GRAYSCALE);
+
+ if ((dwCodecOptions & ENCODE_SMOOTHING) != 0)
+ cinfo.smoothing_factor = m_nSmoothing;
+
+ jpeg_set_quality(&cinfo, GetJpegQuality(), (dwCodecOptions & ENCODE_BASELINE) != 0);
+
+//#ifdef C_PROGRESSIVE_SUPPORTED
+ if ((dwCodecOptions & ENCODE_PROGRESSIVE) != 0)
+ jpeg_simple_progression(&cinfo);
+//#endif
+
+#ifdef C_LOSSLESS_SUPPORTED
+ if ((dwCodecOptions & ENCODE_LOSSLESS) != 0)
+ jpeg_simple_lossless(&cinfo, m_nPredictor, m_nPointTransform);
+#endif
+
+ //SetCodecOption(ENCODE_SUBSAMPLE_444 | GetCodecOption(CXIMAGE_FORMAT_JPG),CXIMAGE_FORMAT_JPG);
+
+ // 2x2, 1x1, 1x1 (4:1:1) : High (default sub sampling)
+ cinfo.comp_info[0].h_samp_factor = 2;
+ cinfo.comp_info[0].v_samp_factor = 2;
+ cinfo.comp_info[1].h_samp_factor = 1;
+ cinfo.comp_info[1].v_samp_factor = 1;
+ cinfo.comp_info[2].h_samp_factor = 1;
+ cinfo.comp_info[2].v_samp_factor = 1;
+
+ if ((dwCodecOptions & ENCODE_SUBSAMPLE_422) != 0){
+ // 2x1, 1x1, 1x1 (4:2:2) : Medium
+ cinfo.comp_info[0].h_samp_factor = 2;
+ cinfo.comp_info[0].v_samp_factor = 1;
+ cinfo.comp_info[1].h_samp_factor = 1;
+ cinfo.comp_info[1].v_samp_factor = 1;
+ cinfo.comp_info[2].h_samp_factor = 1;
+ cinfo.comp_info[2].v_samp_factor = 1;
+ }
+
+ if ((dwCodecOptions & ENCODE_SUBSAMPLE_444) != 0){
+ // 1x1 1x1 1x1 (4:4:4) : None
+ cinfo.comp_info[0].h_samp_factor = 1;
+ cinfo.comp_info[0].v_samp_factor = 1;
+ cinfo.comp_info[1].h_samp_factor = 1;
+ cinfo.comp_info[1].v_samp_factor = 1;
+ cinfo.comp_info[2].h_samp_factor = 1;
+ cinfo.comp_info[2].v_samp_factor = 1;
+ }
+
+ cinfo.density_unit=1;
+ cinfo.X_density=(uint16_t)GetXDPI();
+ cinfo.Y_density=(uint16_t)GetYDPI();
+
+ /* Step 4: Start compressor */
+ /* TRUE ensures that we will write a complete interchange-JPEG file.
+ * Pass TRUE unless you are very sure of what you're doing.
+ */
+ jpeg_start_compress(&cinfo, TRUE);
+
+ /* Step 5: while (scan lines remain to be written) */
+ /* jpeg_write_scanlines(...); */
+ /* Here we use the library's state variable cinfo.next_scanline as the
+ * loop counter, so that we don't have to keep track ourselves.
+ * To keep things simple, we pass one scanline per call; you can pass
+ * more if you wish, though.
+ */
+ row_stride = info.dwEffWidth; /* JSAMPLEs per row in image_buffer */
+
+ //<DP> "8+row_stride" fix heap deallocation problem during debug???
+ buffer = (*cinfo.mem->alloc_sarray)
+ ((j_common_ptr) &cinfo, JPOOL_IMAGE, 8+row_stride, 1);
+
+ CImageIterator iter(this);
+
+ iter.Upset();
+ while (cinfo.next_scanline < cinfo.image_height) {
+ // info.nProgress = (int32_t)(100*cinfo.next_scanline/cinfo.image_height);
+ iter.GetRow(buffer[0], row_stride);
+ // not necessary if swapped red and blue definition in jmorecfg.h;ln322 <W. Morrison>
+ if (head.biClrUsed==0){ // swap R & B for RGB images
+ RGBtoBGR(buffer[0], row_stride); // Lance : 1998/09/01 : Bug ID: EXP-2.1.1-9
+ }
+ iter.PrevRow();
+ (void) jpeg_write_scanlines(&cinfo, buffer, 1);
+ }
+
+ /* Step 6: Finish compression */
+ jpeg_finish_compress(&cinfo);
+
+ /* Step 7: release JPEG compression object */
+ /* This is an important step since it will release a good deal of memory. */
+ jpeg_destroy_compress(&cinfo);
+
+
+#if CXIMAGEJPG_SUPPORT_EXIF
+ if (m_exif && m_exif->m_exifinfo->IsExif){
+ // discard useless sections (if any) read from original image
+ m_exif->DiscardAllButExif();
+ // read new created image, to split the sections
+ hFile->Seek(pos,SEEK_SET);
+ m_exif->DecodeExif(hFile,EXIF_READ_IMAGE);
+ // save back the image, adding EXIF section
+ hFile->Seek(pos,SEEK_SET);
+ m_exif->EncodeExif(hFile);
+ }
+#endif
+
+
+ /* And we're done! */
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_JPG
+
diff --git a/archive/hge/CxImage/ximajpg.h b/archive/hge/CxImage/ximajpg.h new file mode 100644 index 0000000..da21643 --- /dev/null +++ b/archive/hge/CxImage/ximajpg.h @@ -0,0 +1,283 @@ +/*
+ * File: ximajpg.h
+ * Purpose: JPG Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
+ *
+ * Special thanks to Chris Shearer Cooper for CxFileJpg tips & code
+ *
+ * EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
+ *
+ * original CImageJPG and CImageIterator implementation are:
+ * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
+ *
+ * This software is based in part on the work of the Independent JPEG Group.
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * ==========================================================
+ */
+#if !defined(__ximaJPEG_h)
+#define __ximaJPEG_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_JPG
+
+#define CXIMAGEJPG_SUPPORT_EXIF CXIMAGE_SUPPORT_EXIF
+
+extern "C" {
+#ifdef _LINUX
+ #include <jpeglib.h>
+ #include <jerror.h>
+#else
+ #include "../jpeg/jpeglib.h"
+ #include "../jpeg/jerror.h"
+#endif
+}
+
+class DLL_EXP CxImageJPG: public CxImage
+{
+public:
+ CxImageJPG();
+ ~CxImageJPG();
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+/*
+ * EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
+ */
+
+#if CXIMAGEJPG_SUPPORT_EXIF
+
+//--------------------------------------------------------------------------
+// JPEG markers consist of one or more 0xFF bytes, followed by a marker
+// code byte (which is not an FF). Here are the marker codes of interest
+// in this program. (See jdmarker.c for a more complete list.)
+//--------------------------------------------------------------------------
+
+#define M_SOF0 0xC0 // Start Of Frame N
+#define M_SOF1 0xC1 // N indicates which compression process
+#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use
+#define M_SOF3 0xC3
+#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers
+#define M_SOF6 0xC6
+#define M_SOF7 0xC7
+#define M_SOF9 0xC9
+#define M_SOF10 0xCA
+#define M_SOF11 0xCB
+#define M_SOF13 0xCD
+#define M_SOF14 0xCE
+#define M_SOF15 0xCF
+#define M_SOI 0xD8 // Start Of Image (beginning of datastream)
+#define M_EOI 0xD9 // End Of Image (end of datastream)
+#define M_SOS 0xDA // Start Of Scan (begins compressed data)
+#define M_JFIF 0xE0 // Jfif marker
+#define M_EXIF 0xE1 // Exif marker
+#define M_COM 0xFE // COMment
+
+#define PSEUDO_IMAGE_MARKER 0x123; // Extra value.
+
+#define EXIF_READ_EXIF 0x01
+#define EXIF_READ_IMAGE 0x02
+#define EXIF_READ_ALL 0x03
+
+class DLL_EXP CxExifInfo
+{
+
+typedef struct tag_Section_t{
+ uint8_t* Data;
+ int32_t Type;
+ unsigned Size;
+} Section_t;
+
+public:
+ EXIFINFO* m_exifinfo;
+ char m_szLastError[256];
+ CxExifInfo(EXIFINFO* info = NULL);
+ ~CxExifInfo();
+ bool DecodeExif(CxFile * hFile, int32_t nReadMode = EXIF_READ_EXIF);
+ bool EncodeExif(CxFile * hFile);
+ void DiscardAllButExif();
+protected:
+ bool process_EXIF(uint8_t * CharBuf, uint32_t length);
+ void process_COM (const uint8_t * Data, int32_t length);
+ void process_SOFn (const uint8_t * Data, int32_t marker);
+ int32_t Get16u(void * Short);
+ int32_t Get16m(void * Short);
+ int32_t Get32s(void * Long);
+ uint32_t Get32u(void * Long);
+ double ConvertAnyFormat(void * ValuePtr, int32_t Format);
+ void* FindSection(int32_t SectionType);
+ bool ProcessExifDir(uint8_t * DirStart, uint8_t * OffsetBase, unsigned ExifLength,
+ EXIFINFO * const pInfo, uint8_t ** const LastExifRefdP, int32_t NestingLevel=0);
+ int32_t ExifImageWidth;
+ int32_t MotorolaOrder;
+ Section_t Sections[MAX_SECTIONS];
+ int32_t SectionsRead;
+ bool freeinfo;
+};
+
+ CxExifInfo* m_exif;
+ bool DecodeExif(CxFile * hFile);
+ bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); }
+ bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type);
+
+#endif //CXIMAGEJPG_SUPPORT_EXIF
+
+////////////////////////////////////////////////////////////////////////////////////////
+////////////////////// C x F i l e J p g ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////
+
+// thanks to Chris Shearer Cooper <cscooper(at)frii(dot)com>
+class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr
+ {
+public:
+ enum { eBufSize = 4096 };
+
+ CxFileJpg(CxFile* pFile)
+ {
+ m_pFile = pFile;
+
+ init_destination = InitDestination;
+ empty_output_buffer = EmptyOutputBuffer;
+ term_destination = TermDestination;
+
+ init_source = InitSource;
+ fill_input_buffer = FillInputBuffer;
+ skip_input_data = SkipInputData;
+ resync_to_restart = jpeg_resync_to_restart; // use default method
+ term_source = TermSource;
+ next_input_byte = NULL; //* => next byte to read from buffer
+ bytes_in_buffer = 0; //* # of bytes remaining in buffer
+
+ m_pBuffer = new uint8_t[eBufSize];
+ }
+ ~CxFileJpg()
+ {
+ delete [] m_pBuffer;
+ }
+
+ static void InitDestination(j_compress_ptr cinfo)
+ {
+ CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
+ pDest->next_output_byte = pDest->m_pBuffer;
+ pDest->free_in_buffer = eBufSize;
+ }
+
+ static boolean EmptyOutputBuffer(j_compress_ptr cinfo)
+ {
+ CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
+ if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize)
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+ pDest->next_output_byte = pDest->m_pBuffer;
+ pDest->free_in_buffer = eBufSize;
+ return TRUE;
+ }
+
+ static void TermDestination(j_compress_ptr cinfo)
+ {
+ CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
+ size_t datacount = eBufSize - pDest->free_in_buffer;
+ /* Write any data remaining in the buffer */
+ if (datacount > 0) {
+ if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount))
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+ }
+ pDest->m_pFile->Flush();
+ /* Make sure we wrote the output file OK */
+ if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE);
+ return;
+ }
+
+ static void InitSource(j_decompress_ptr cinfo)
+ {
+ CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
+ pSource->m_bStartOfFile = TRUE;
+ }
+
+ static boolean FillInputBuffer(j_decompress_ptr cinfo)
+ {
+ size_t nbytes;
+ CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
+ nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize);
+ if (nbytes <= 0){
+ if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ // Insert a fake EOI marker
+ pSource->m_pBuffer[0] = (JOCTET) 0xFF;
+ pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI;
+ nbytes = 2;
+ }
+ pSource->next_input_byte = pSource->m_pBuffer;
+ pSource->bytes_in_buffer = nbytes;
+ pSource->m_bStartOfFile = FALSE;
+ return TRUE;
+ }
+
+ static void SkipInputData(j_decompress_ptr cinfo, long num_bytes)
+ {
+ CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
+ if (num_bytes > 0){
+ while (num_bytes > (int32_t)pSource->bytes_in_buffer){
+ num_bytes -= (int32_t)pSource->bytes_in_buffer;
+ FillInputBuffer(cinfo);
+ // note we assume that fill_input_buffer will never return FALSE,
+ // so suspension need not be handled.
+ }
+ pSource->next_input_byte += (size_t) num_bytes;
+ pSource->bytes_in_buffer -= (size_t) num_bytes;
+ }
+ }
+
+ static void TermSource(j_decompress_ptr /*cinfo*/)
+ {
+ return;
+ }
+protected:
+ CxFile *m_pFile;
+ uint8_t *m_pBuffer;
+ bool m_bStartOfFile;
+};
+
+public:
+ enum CODEC_OPTION
+ {
+ ENCODE_BASELINE = 0x1,
+ ENCODE_ARITHMETIC = 0x2,
+ ENCODE_GRAYSCALE = 0x4,
+ ENCODE_OPTIMIZE = 0x8,
+ ENCODE_PROGRESSIVE = 0x10,
+ ENCODE_LOSSLESS = 0x20,
+ ENCODE_SMOOTHING = 0x40,
+ DECODE_GRAYSCALE = 0x80,
+ DECODE_QUANTIZE = 0x100,
+ DECODE_DITHER = 0x200,
+ DECODE_ONEPASS = 0x400,
+ DECODE_NOSMOOTH = 0x800,
+ ENCODE_SUBSAMPLE_422 = 0x1000,
+ ENCODE_SUBSAMPLE_444 = 0x2000
+ };
+
+ int32_t m_nPredictor;
+ int32_t m_nPointTransform;
+ int32_t m_nSmoothing;
+ int32_t m_nQuantize;
+ J_DITHER_MODE m_nDither;
+
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximalpha.cpp b/archive/hge/CxImage/ximalpha.cpp new file mode 100644 index 0000000..2932068 --- /dev/null +++ b/archive/hge/CxImage/ximalpha.cpp @@ -0,0 +1,367 @@ +// xImalpha.cpp : Alpha channel functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_ALPHA
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa AlphaSetMax
+ */
+uint8_t CxImage::AlphaGetMax() const
+{
+ return info.nAlphaMax;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets global Alpha (opacity) value applied to the whole image,
+ * valid only for painting functions.
+ * \param nAlphaMax: can be from 0 to 255
+ */
+void CxImage::AlphaSetMax(uint8_t nAlphaMax)
+{
+ info.nAlphaMax=nAlphaMax;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the image has a valid alpha channel.
+ */
+bool CxImage::AlphaIsValid()
+{
+ return pAlpha!=0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Enables the alpha palette, so the Draw() function changes its behavior.
+ */
+void CxImage::AlphaPaletteEnable(bool enable)
+{
+ info.bAlphaPaletteEnabled=enable;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * True if the alpha palette is enabled for painting.
+ */
+bool CxImage::AlphaPaletteIsEnabled()
+{
+ return info.bAlphaPaletteEnabled;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the alpha channel to full transparent. AlphaSet(0) has the same effect
+ */
+void CxImage::AlphaClear()
+{
+ if (pAlpha) memset(pAlpha,0,head.biWidth * head.biHeight);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the alpha level for the whole image.
+ * \param level : from 0 (transparent) to 255 (opaque)
+ */
+void CxImage::AlphaSet(uint8_t level)
+{
+ if (pAlpha) memset(pAlpha,level,head.biWidth * head.biHeight);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Allocates an empty (opaque) alpha channel.
+ */
+bool CxImage::AlphaCreate()
+{
+ if (pAlpha==NULL) {
+ pAlpha = (uint8_t*)malloc(head.biWidth * head.biHeight);
+ if (pAlpha) memset(pAlpha,255,head.biWidth * head.biHeight);
+ }
+ return (pAlpha!=0);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::AlphaDelete()
+{
+ if (pAlpha) { free(pAlpha); pAlpha=0; }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::AlphaInvert()
+{
+ if (pAlpha) {
+ uint8_t *iSrc=pAlpha;
+ int32_t n=head.biHeight*head.biWidth;
+ for(int32_t i=0; i < n; i++){
+ *iSrc=(uint8_t)~(*(iSrc));
+ iSrc++;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Imports an existing alpa channel from another image with the same width and height.
+ */
+bool CxImage::AlphaCopy(CxImage &from)
+{
+ if (from.pAlpha == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
+ if (pAlpha==NULL) pAlpha = (uint8_t*)malloc(head.biWidth * head.biHeight);
+ if (pAlpha==NULL) return false;
+ memcpy(pAlpha,from.pAlpha,head.biWidth * head.biHeight);
+ info.nAlphaMax=from.info.nAlphaMax;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Creates the alpha channel from a gray scale image.
+ */
+bool CxImage::AlphaSet(CxImage &from)
+{
+ if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
+ if (pAlpha==NULL) pAlpha = (uint8_t*)malloc(head.biWidth * head.biHeight);
+ uint8_t* src = from.info.pImage;
+ uint8_t* dst = pAlpha;
+ if (src==NULL || dst==NULL) return false;
+ for (int32_t y=0; y<head.biHeight; y++){
+ memcpy(dst,src,head.biWidth);
+ dst += head.biWidth;
+ src += from.info.dwEffWidth;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the alpha level for a single pixel
+ */
+void CxImage::AlphaSet(const int32_t x,const int32_t y,const uint8_t level)
+{
+ if (pAlpha && IsInside(x,y)) pAlpha[x+y*head.biWidth]=level;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Gets the alpha level for a single pixel
+ */
+uint8_t CxImage::AlphaGet(const int32_t x,const int32_t y)
+{
+ if (pAlpha && IsInside(x,y)) return pAlpha[x+y*head.biWidth];
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns pointer to alpha data for pixel (x,y).
+ *
+ * \author ***bd*** 2.2004
+ */
+uint8_t* CxImage::AlphaGetPointer(const int32_t x,const int32_t y)
+{
+ if (pAlpha && IsInside(x,y)) return pAlpha+x+y*head.biWidth;
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Get alpha value without boundscheck (a bit faster). Pixel must be inside the image.
+ *
+ * \author ***bd*** 2.2004
+ */
+uint8_t CxImage::BlindAlphaGet(const int32_t x,const int32_t y)
+{
+#ifdef _DEBUG
+ if (!IsInside(x,y) || (pAlpha==0))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return 0;
+ #endif
+#endif
+ return pAlpha[x+y*head.biWidth];
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Resets the alpha palette
+ */
+void CxImage::AlphaPaletteClear()
+{
+ RGBQUAD c;
+ for(uint16_t ip=0; ip<head.biClrUsed;ip++){
+ c=GetPaletteColor((uint8_t)ip);
+ c.rgbReserved=0;
+ SetPaletteColor((uint8_t)ip,c);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the image has a valid alpha palette.
+ */
+bool CxImage::AlphaPaletteIsValid()
+{
+ RGBQUAD c;
+ for(uint16_t ip=0; ip<head.biClrUsed;ip++){
+ c=GetPaletteColor((uint8_t)ip);
+ if (c.rgbReserved != 0) return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Blends the alpha channel and the alpha palette with the pixels. The result is a 24 bit image.
+ * The background color can be selected using SetTransColor().
+ */
+void CxImage::AlphaStrip()
+{
+ bool bAlphaPaletteIsValid = AlphaPaletteIsValid();
+ bool bAlphaIsValid = AlphaIsValid();
+ if (!(bAlphaIsValid || bAlphaPaletteIsValid)) return;
+ RGBQUAD c;
+ int32_t a, a1;
+ if (head.biBitCount==24){
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ c = BlindGetPixelColor(x,y);
+ if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
+ a1 = 256-a;
+ c.rgbBlue = (uint8_t)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
+ c.rgbGreen = (uint8_t)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
+ c.rgbRed = (uint8_t)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
+ BlindSetPixelColor(x,y,c);
+ }
+ }
+ AlphaDelete();
+ } else {
+ CxImage tmp(head.biWidth,head.biHeight,24);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return;
+ }
+
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ c = BlindGetPixelColor(x,y);
+ if (bAlphaIsValid) a=(BlindAlphaGet(x,y)*info.nAlphaMax)/255; else a=info.nAlphaMax;
+ if (bAlphaPaletteIsValid) a=(c.rgbReserved*a)/255;
+ a1 = 256-a;
+ c.rgbBlue = (uint8_t)((c.rgbBlue * a + a1 * info.nBkgndColor.rgbBlue)>>8);
+ c.rgbGreen = (uint8_t)((c.rgbGreen * a + a1 * info.nBkgndColor.rgbGreen)>>8);
+ c.rgbRed = (uint8_t)((c.rgbRed * a + a1 * info.nBkgndColor.rgbRed)>>8);
+ tmp.BlindSetPixelColor(x,y,c);
+ }
+ }
+ Transfer(tmp);
+ }
+ return;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::AlphaFlip()
+{
+ if (!pAlpha) return false;
+
+ uint8_t *buff = (uint8_t*)malloc(head.biWidth);
+ if (!buff) return false;
+
+ uint8_t *iSrc,*iDst;
+ iSrc = pAlpha + (head.biHeight-1)*head.biWidth;
+ iDst = pAlpha;
+ for (int32_t i=0; i<(head.biHeight/2); ++i)
+ {
+ memcpy(buff, iSrc, head.biWidth);
+ memcpy(iSrc, iDst, head.biWidth);
+ memcpy(iDst, buff, head.biWidth);
+ iSrc-=head.biWidth;
+ iDst+=head.biWidth;
+ }
+
+ free(buff);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::AlphaMirror()
+{
+ if (!pAlpha) return false;
+ uint8_t* pAlpha2 = (uint8_t*)malloc(head.biWidth * head.biHeight);
+ if (!pAlpha2) return false;
+ uint8_t *iSrc,*iDst;
+ int32_t wdt=head.biWidth-1;
+ iSrc=pAlpha + wdt;
+ iDst=pAlpha2;
+ for(int32_t y=0; y < head.biHeight; y++){
+ for(int32_t x=0; x <= wdt; x++)
+ *(iDst+x)=*(iSrc-x);
+ iSrc+=head.biWidth;
+ iDst+=head.biWidth;
+ }
+ free(pAlpha);
+ pAlpha=pAlpha2;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Exports the alpha channel in a 8bpp grayscale image.
+ */
+bool CxImage::AlphaSplit(CxImage *dest)
+{
+ if (!pAlpha || !dest) return false;
+
+ CxImage tmp(head.biWidth,head.biHeight,8);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ uint8_t* src = pAlpha;
+ uint8_t* dst = tmp.info.pImage;
+ for (int32_t y=0; y<head.biHeight; y++){
+ memcpy(dst,src,head.biWidth);
+ dst += tmp.info.dwEffWidth;
+ src += head.biWidth;
+ }
+
+ tmp.SetGrayPalette();
+ dest->Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Exports the alpha palette channel in a 8bpp grayscale image.
+ */
+bool CxImage::AlphaPaletteSplit(CxImage *dest)
+{
+ if (!AlphaPaletteIsValid() || !dest) return false;
+
+ CxImage tmp(head.biWidth,head.biHeight,8);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ tmp.BlindSetPixelIndex(x,y,BlindGetPixelColor(x,y).rgbReserved);
+ }
+ }
+
+ tmp.SetGrayPalette();
+ dest->Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Merge in the alpha layer the transparent color mask
+ * (previously set with SetTransColor or SetTransIndex)
+ */
+bool CxImage::AlphaFromTransparency()
+{
+ if (!IsValid() || !IsTransparent())
+ return false;
+
+ AlphaCreate();
+
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ if (IsTransparent(x,y)){
+ AlphaSet(x,y,0);
+ }
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_ALPHA
diff --git a/archive/hge/CxImage/ximalyr.cpp b/archive/hge/CxImage/ximalyr.cpp new file mode 100644 index 0000000..23dc226 --- /dev/null +++ b/archive/hge/CxImage/ximalyr.cpp @@ -0,0 +1,116 @@ +// xImaLyr.cpp : Layers functions
+/* 21/04/2003 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_LAYERS
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * If the object is an internal layer, GetParent return its parent in the hierarchy.
+ */
+CxImage* CxImage::GetParent() const
+{
+ return info.pParent;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Number of layers allocated directly by the object.
+ */
+int32_t CxImage::GetNumLayers() const
+{
+ return info.nNumLayers;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Creates an empty layer. If position is less than 0, the new layer will be placed in the last position
+ */
+bool CxImage::LayerCreate(int32_t position)
+{
+ if ( position < 0 || position > info.nNumLayers ) position = info.nNumLayers;
+
+ CxImage** ptmp = new CxImage*[info.nNumLayers + 1];
+ if (ptmp==0) return false;
+
+ int32_t i=0;
+ for (int32_t n=0; n<info.nNumLayers; n++){
+ if (position == n){
+ ptmp[n] = new CxImage();
+ i=1;
+ }
+ ptmp[n+i]=ppLayers[n];
+ }
+ if (i==0) ptmp[info.nNumLayers] = new CxImage();
+
+ if (ptmp[position]){
+ ptmp[position]->info.pParent = this;
+ } else {
+ free(ptmp);
+ return false;
+ }
+
+ info.nNumLayers++;
+ delete [] ppLayers;
+ ppLayers = ptmp;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Deletes a layer. If position is less than 0, the last layer will be deleted
+ */
+bool CxImage::LayerDelete(int32_t position)
+{
+ if ( position >= info.nNumLayers ) return false;
+ if ( position < 0) position = info.nNumLayers - 1;
+ if ( position < 0) return false;
+
+ if (info.nNumLayers>1){
+
+ CxImage** ptmp = new CxImage*[info.nNumLayers - 1];
+ if (ptmp==0) return false;
+
+ int32_t i=0;
+ for (int32_t n=0; n<info.nNumLayers; n++){
+ if (position == n){
+ delete ppLayers[n];
+ i=1;
+ }
+ ptmp[n]=ppLayers[n+i];
+ }
+
+ info.nNumLayers--;
+ delete [] ppLayers;
+ ppLayers = ptmp;
+
+ } else {
+ delete ppLayers[0];
+ delete [] ppLayers;
+ ppLayers = 0;
+ info.nNumLayers = 0;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::LayerDeleteAll()
+{
+ if (ppLayers) {
+ for(int32_t n=0; n<info.nNumLayers;n++){ delete ppLayers[n]; }
+ delete [] ppLayers; ppLayers=0; info.nNumLayers = 0;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns a pointer to a layer. If position is less than 0, the last layer will be returned
+ */
+CxImage* CxImage::GetLayer(int32_t position)
+{
+ if ( ppLayers == NULL) return NULL;
+ if ( info.nNumLayers == 0) return NULL;
+ if ( position >= info.nNumLayers ) return NULL;
+ if ( position < 0) position = info.nNumLayers - 1;
+ return ppLayers[position];
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_LAYERS
diff --git a/archive/hge/CxImage/ximamng.cpp b/archive/hge/CxImage/ximamng.cpp new file mode 100644 index 0000000..d5ea82e --- /dev/null +++ b/archive/hge/CxImage/ximamng.cpp @@ -0,0 +1,430 @@ +/*
+ * File: ximamng.cpp
+ * Purpose: Platform Independent MNG Image Class Loader and Writer
+ * Author: 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximamng.h"
+
+#if CXIMAGE_SUPPORT_MNG
+
+////////////////////////////////////////////////////////////////////////////////
+// callbacks for the mng decoder:
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+// memory allocation; data must be zeroed
+static mng_ptr
+mymngalloc( mng_size_t size )
+{
+ return (mng_ptr)calloc(1, size);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// memory deallocation
+static void mymngfree(mng_ptr p, mng_size_t size)
+{
+ free(p);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Stream open/close:
+// since the user is responsible for opening and closing the file,
+// we leave the default implementation open
+static mng_bool mymngopenstream(mng_handle mng) { return MNG_TRUE; }
+static mng_bool mymngopenstreamwrite(mng_handle mng) { return MNG_TRUE; }
+static mng_bool mymngclosestream(mng_handle mng) { return MNG_TRUE; }
+
+////////////////////////////////////////////////////////////////////////////////
+// feed data to the decoder
+static mng_bool mymngreadstream(mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread)
+{
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+ // read the requested amount of data from the file
+ *bytesread = mymng->file->Read( buffer, sizeof(uint8_t), size);
+ return MNG_TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static mng_bool mymngwritestream (mng_handle mng, mng_ptr pBuf, mng_uint32 iSize, mng_uint32 *iWritten)
+{
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+ // write it
+ *iWritten = mymng->file->Write (pBuf, 1, iSize);
+ return MNG_TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// the header's been read. set up the display stuff
+static mng_bool mymngprocessheader( mng_handle mng, mng_uint32 width, mng_uint32 height )
+{
+ // normally the image buffer is allocated here,
+ // but in this module we don't know nothing about
+ // the final environment.
+
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+
+ mymng->width = width;
+ mymng->height = height;
+ mymng->bpp = 24;
+ mymng->effwdt = ((((width * mymng->bpp) + 31) >> 5) << 2);
+
+ if (mng->bUseBKGD){
+ mymng->nBkgndIndex = 0;
+ mymng->nBkgndColor.rgbRed = mng->iBGred >> 8;
+ mymng->nBkgndColor.rgbGreen =mng->iBGgreen >> 8;
+ mymng->nBkgndColor.rgbBlue = mng->iBGblue >> 8;
+ }
+
+ mymng->image = (uint8_t*)malloc(height * mymng->effwdt);
+
+ // tell the mng decoder about our bit-depth choice
+#if CXIMAGE_SUPPORT_ALPHA
+ mng_set_canvasstyle( mng, MNG_CANVAS_RGB8_A8 );
+ mymng->alpha = (uint8_t*)malloc(height * width);
+#else
+ mng_set_canvasstyle( mng, MNG_CANVAS_BGR8);
+ mymng->alpha = NULL;
+#endif
+ return MNG_TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// return a row pointer for the decoder to fill
+static mng_ptr mymnggetcanvasline( mng_handle mng, mng_uint32 line )
+{
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+ return (mng_ptr)(mymng->image + (mymng->effwdt * (mymng->height - 1 - line)));
+}
+////////////////////////////////////////////////////////////////////////////////
+// return a row pointer for the decoder to fill for alpha channel
+static mng_ptr mymnggetalphaline( mng_handle mng, mng_uint32 line )
+{
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+ return (mng_ptr)(mymng->alpha + (mymng->width * (mymng->height - 1 - line)));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// timer
+static mng_uint32 mymnggetticks(mng_handle mng)
+{
+#ifdef WIN32
+ return (mng_uint32)GetTickCount();
+#else
+ return 0;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Refresh: actual frame need to be updated (Invalidate)
+static mng_bool mymngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h)
+{
+// mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+ return MNG_TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// interframe delay callback
+static mng_bool mymngsettimer(mng_handle mng, mng_uint32 msecs)
+{
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(mng);
+ mymng->delay = msecs; // set the timer for when the decoder wants to be woken
+ return MNG_TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static mng_bool mymngerror(mng_handle mng, mng_int32 code, mng_int8 severity, mng_chunkid chunktype, mng_uint32 chunkseq, mng_int32 extra1, mng_int32 extra2, mng_pchar text)
+{
+ return mng_cleanup(&mng); //<Arkadiy Olovyannikov>
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CxImage members
+////////////////////////////////////////////////////////////////////////////////
+CxImageMNG::CxImageMNG(): CxImage(CXIMAGE_FORMAT_MNG)
+{
+ hmng = NULL;
+ memset(&mnginfo,0,sizeof(mngstuff));
+ mnginfo.nBkgndIndex = -1;
+ mnginfo.speed = 1.0f;
+}
+////////////////////////////////////////////////////////////////////////////////
+CxImageMNG::~CxImageMNG()
+{
+ // cleanup and return
+ if (mnginfo.thread){ //close the animation thread
+ mnginfo.animation_enabled=0;
+ ResumeThread(mnginfo.thread);
+ WaitForSingleObject(mnginfo.thread,500);
+ CloseHandle(mnginfo.thread);
+ }
+ // free objects
+ if (mnginfo.image) free(mnginfo.image);
+ if (mnginfo.alpha) free(mnginfo.alpha);
+ if (hmng) mng_cleanup(&hmng); //be sure it's not needed any more. (active timers ?)
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageMNG::SetCallbacks(mng_handle mng)
+{
+ // set the callbacks
+ mng_setcb_errorproc(mng, mymngerror);
+ mng_setcb_openstream(mng, mymngopenstream);
+ mng_setcb_closestream(mng, mymngclosestream);
+ mng_setcb_readdata(mng, mymngreadstream);
+ mng_setcb_processheader(mng, mymngprocessheader);
+ mng_setcb_getcanvasline(mng, mymnggetcanvasline);
+ mng_setcb_refresh(mng, mymngrefresh);
+ mng_setcb_gettickcount(mng, mymnggetticks);
+ mng_setcb_settimer(mng, mymngsettimer);
+ mng_setcb_refresh(mng, mymngrefresh);
+ mng_setcb_getalphaline(mng, mymnggetalphaline);
+}
+////////////////////////////////////////////////////////////////////////////////
+// can't use the CxImage implementation because it looses mnginfo
+bool CxImageMNG::Load(const TCHAR * imageFileName){
+ FILE* hFile; //file handle to read the image
+#ifdef WIN32
+ if ((hFile=_tfopen(imageFileName,_T("rb")))==NULL) return false; // For UNICODE support
+#else
+ if ((hFile=fopen(imageFileName,"rb"))==NULL) return false;
+#endif
+ bool bOK = Decode(hFile);
+ fclose(hFile);
+ return bOK;
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageMNG::Decode(CxFile *hFile)
+{
+ if (hFile == NULL) return false;
+
+ cx_try
+ {
+ // set up the mng decoder for our stream
+ hmng = mng_initialize(&mnginfo, (mng_memalloc)mymngalloc, (mng_memfree)mymngfree, MNG_NULL);
+ if (hmng == NULL) cx_throw("could not initialize libmng");
+
+ // set the file we want to play
+ mnginfo.file = hFile;
+
+ // Set the colorprofile, lcms uses this:
+ mng_set_srgb(hmng, MNG_TRUE );
+ // Set white as background color:
+ uint16_t Red,Green,Blue;
+ Red = Green = Blue = (255 << 8) + 255;
+ mng_set_bgcolor(hmng, Red, Green, Blue );
+ // If PNG Background is available, use it:
+ mng_set_usebkgd(hmng, MNG_TRUE );
+
+ // No need to store chunks:
+ mng_set_storechunks(hmng, MNG_FALSE);
+ // No need to wait: straight reading
+ mng_set_suspensionmode(hmng, MNG_FALSE);
+
+ SetCallbacks(hmng);
+
+ mng_datap pData = (mng_datap)hmng;
+
+ // read in the image
+ info.nNumFrames=0;
+ int32_t retval=MNG_NOERROR;
+
+ retval = mng_readdisplay(hmng);
+
+ if (retval != MNG_NOERROR && retval != MNG_NEEDTIMERWAIT){
+ mng_store_error(hmng,retval,0,0);
+ if (hmng->zErrortext){
+ cx_throw(hmng->zErrortext);
+ } else {
+ cx_throw("Error in MNG file");
+ }
+ }
+
+ if (info.nEscape == -1) {
+ // Return output dimensions only
+ head.biWidth = hmng->iWidth;
+ head.biHeight = hmng->iHeight;
+ info.dwType = CXIMAGE_FORMAT_MNG;
+ return true;
+ }
+
+ // read all
+ while(pData->bReading){
+ retval = mng_display_resume(hmng);
+ info.nNumFrames++;
+ }
+
+ // single frame check:
+ if (retval != MNG_NEEDTIMERWAIT){
+ info.nNumFrames--;
+ } else {
+ mnginfo.animation=1;
+ }
+
+ if (info.nNumFrames<=0) info.nNumFrames=1;
+
+ if (mnginfo.animation_enabled==0){
+ // select the frame
+ if (info.nFrame>=0 && info.nFrame<info.nNumFrames){
+ for (int32_t n=0;n<info.nFrame;n++) mng_display_resume(hmng);
+ } else cx_throw("Error: frame not present in MNG file");
+ }
+
+ if (mnginfo.nBkgndIndex >= 0){
+ info.nBkgndIndex = mnginfo.nBkgndIndex;
+ info.nBkgndColor.rgbRed = mnginfo.nBkgndColor.rgbRed;
+ info.nBkgndColor.rgbGreen = mnginfo.nBkgndColor.rgbGreen;
+ info.nBkgndColor.rgbBlue = mnginfo.nBkgndColor.rgbBlue;
+ }
+
+ //store the newly created image
+ if (Create(mnginfo.width,mnginfo.height,mnginfo.bpp, CXIMAGE_FORMAT_MNG)){
+ memcpy(GetBits(), mnginfo.image, info.dwEffWidth * head.biHeight);
+#if CXIMAGE_SUPPORT_ALPHA
+ SwapRGB2BGR();
+ AlphaCreate();
+ if(AlphaIsValid() && mnginfo.alpha){
+ memcpy(AlphaGetPointer(),mnginfo.alpha,mnginfo.width * mnginfo.height);
+ }
+#endif
+ } else cx_throw("CxImageMNG::Decode cannot create image");
+
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageMNG::Encode(CxFile *hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ cx_try
+ {
+ if (head.biClrUsed != 0) cx_throw("MNG encoder can save only RGB images");
+ // set the file we want to play
+ mnginfo.file = hFile;
+ mnginfo.bpp = head.biBitCount;
+ mnginfo.effwdt = info.dwEffWidth;
+ mnginfo.height = head.biHeight;
+ mnginfo.width = head.biWidth;
+
+ mnginfo.image = (uint8_t*)malloc(head.biSizeImage);
+ if (mnginfo.image == NULL) cx_throw("could not allocate memory for MNG");
+ memcpy(mnginfo.image,info.pImage, head.biSizeImage);
+
+ // set up the mng decoder for our stream
+ hmng = mng_initialize(&mnginfo, (mng_memalloc)mymngalloc, (mng_memfree)mymngfree, MNG_NULL);
+ if (hmng == NULL) cx_throw("could not initialize libmng");
+
+ mng_setcb_openstream(hmng, mymngopenstreamwrite );
+ mng_setcb_closestream(hmng, mymngclosestream);
+ mng_setcb_writedata(hmng, mymngwritestream);
+
+ // Write File:
+ mng_create(hmng);
+ // Just a single Frame (save a normal PNG):
+ WritePNG(hmng, 0, 1 );
+ // Now write file:
+ mng_write(hmng);
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+// Writes a single PNG datastream
+void CxImageMNG::WritePNG( mng_handle hMNG, int32_t Frame, int32_t FrameCount )
+{
+ mngstuff *mymng = (mngstuff *)mng_get_userdata(hMNG);
+
+ int32_t OffsetX=0,OffsetY=0,OffsetW=mymng->width,OffsetH=mymng->height;
+
+ uint8_t *tmpbuffer = new uint8_t[ (mymng->effwdt+1) * mymng->height];
+ if( tmpbuffer == 0 ) return;
+
+ // Write DEFI chunk.
+ mng_putchunk_defi( hMNG, 0, 0, 0, MNG_TRUE, OffsetX, OffsetY, MNG_FALSE, 0, 0, 0, 0 );
+
+ // Write Header:
+ mng_putchunk_ihdr(
+ hMNG,
+ OffsetW, OffsetH,
+ MNG_BITDEPTH_8,
+ MNG_COLORTYPE_RGB,
+ MNG_COMPRESSION_DEFLATE,
+ MNG_FILTER_ADAPTIVE,
+ MNG_INTERLACE_NONE
+ );
+
+ // transfer data, add Filterbyte:
+ for( int32_t Row=0; Row<OffsetH; Row++ ){
+ // First Byte in each Scanline is Filterbyte: Currently 0 -> No Filter.
+ tmpbuffer[Row*(mymng->effwdt+1)]=0;
+ // Copy the scanline: (reverse order)
+ memcpy(tmpbuffer+Row*(mymng->effwdt+1)+1,
+ mymng->image+((OffsetH-1-(OffsetY+Row))*(mymng->effwdt))+OffsetX,mymng->effwdt);
+ // swap red and blue components
+ RGBtoBGR(tmpbuffer+Row*(mymng->effwdt+1)+1,mymng->effwdt);
+ }
+
+ // Compress data with ZLib (Deflate):
+ uint8_t *dstbuffer = new uint8_t[(mymng->effwdt+1)*OffsetH];
+ if( dstbuffer == 0 ) return;
+ uint32_t dstbufferSize=(mymng->effwdt+1)*OffsetH;
+
+ // Compress data:
+ if(Z_OK != compress2((Bytef *)dstbuffer,(ULONG *)&dstbufferSize,(const Bytef*)tmpbuffer,
+ (ULONG) (mymng->effwdt+1)*OffsetH,9 )) return;
+
+ // Write Data into MNG File:
+ mng_putchunk_idat( hMNG, dstbufferSize, (mng_ptr*)dstbuffer);
+ mng_putchunk_iend(hMNG);
+
+ // Free the stuff:
+ delete [] tmpbuffer;
+ delete [] dstbuffer;
+}
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImageMNG::Resume()
+{
+ if (MNG_NEEDTIMERWAIT == mng_display_resume(hmng)){
+ if (info.pImage==NULL){
+ Create(mnginfo.width,mnginfo.height,mnginfo.bpp, CXIMAGE_FORMAT_MNG);
+ }
+ if (IsValid()){
+ memcpy(GetBits(), mnginfo.image, info.dwEffWidth * head.biHeight);
+#if CXIMAGE_SUPPORT_ALPHA
+ SwapRGB2BGR();
+ AlphaCreate();
+ if(AlphaIsValid() && mnginfo.alpha){
+ memcpy(AlphaGetPointer(),mnginfo.alpha,mnginfo.width * mnginfo.height);
+ }
+#endif
+ }
+ } else {
+ mnginfo.animation_enabled = 0;
+ }
+ return mnginfo.animation_enabled;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageMNG::SetSpeed(float speed)
+{
+ if (speed>10.0) mnginfo.speed = 10.0f;
+ else if (speed<0.1) mnginfo.speed = 0.1f;
+ else mnginfo.speed=speed;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_MNG
diff --git a/archive/hge/CxImage/ximamng.h b/archive/hge/CxImage/ximamng.h new file mode 100644 index 0000000..9466fc2 --- /dev/null +++ b/archive/hge/CxImage/ximamng.h @@ -0,0 +1,88 @@ +/*
+ * File: ximamng.h
+ * Purpose: Declaration of the MNG Image Class
+ * Author: Davide Pizzolato - www.xdp.it
+ * Created: 2001
+ */
+/* ==========================================================
+ * CxImageMNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Special thanks to Frank Haug <f.haug(at)jdm(dot)de> for suggestions and code.
+ *
+ * original mng.cpp code created by Nikolaus Brennig, November 14th, 2000. <virtualnik(at)nol(dot)at>
+ *
+ * LIBMNG Copyright (c) 2000,2001 Gerard Juyn (gerard@libmng.com)
+ * ==========================================================
+ */
+
+#if !defined(__ximaMNG_h)
+#define __ximaMNG_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_MNG
+
+//#define MNG_NO_CMS
+#define MNG_SUPPORT_DISPLAY
+#define MNG_SUPPORT_READ
+#define MNG_SUPPORT_WRITE
+#define MNG_ACCESS_CHUNKS
+#define MNG_STORE_CHUNKS
+
+extern "C" {
+#include "../mng/libmng.h"
+#include "../mng/libmng_data.h"
+#include "../mng/libmng_error.h"
+}
+
+//uint32_t _stdcall RunMNGThread(void *lpParam);
+
+typedef struct tagmngstuff
+{
+ CxFile *file;
+ uint8_t *image;
+ uint8_t *alpha;
+ HANDLE thread;
+ mng_uint32 delay;
+ mng_uint32 width;
+ mng_uint32 height;
+ mng_uint32 effwdt;
+ mng_int16 bpp;
+ mng_bool animation;
+ mng_bool animation_enabled;
+ float speed;
+ int32_t nBkgndIndex;
+ RGBQUAD nBkgndColor;
+} mngstuff;
+
+class CxImageMNG: public CxImage
+{
+public:
+ CxImageMNG();
+ ~CxImageMNG();
+
+ bool Load(const TCHAR * imageFileName);
+
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+ bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_MNG);}
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+ int32_t Resume();
+ void SetSpeed(float speed);
+
+ mng_handle hmng;
+ mngstuff mnginfo;
+protected:
+ void WritePNG(mng_handle hMNG, int32_t Frame, int32_t FrameCount );
+ void SetCallbacks(mng_handle mng);
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximapal.cpp b/archive/hge/CxImage/ximapal.cpp new file mode 100644 index 0000000..fe0615b --- /dev/null +++ b/archive/hge/CxImage/ximapal.cpp @@ -0,0 +1,834 @@ +// xImaPal.cpp : Palette and Pixel functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * returns the palette dimension in byte
+ */
+uint32_t CxImage::GetPaletteSize()
+{
+ return (head.biClrUsed * sizeof(RGBQUAD));
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPaletteColor(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t alpha)
+{
+ if ((pDib)&&(head.biClrUsed)){
+ uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
+ if (idx<head.biClrUsed){
+ int32_t ldx=idx*sizeof(RGBQUAD);
+ iDst[ldx++] = (uint8_t) b;
+ iDst[ldx++] = (uint8_t) g;
+ iDst[ldx++] = (uint8_t) r;
+ iDst[ldx] = (uint8_t) alpha;
+ info.last_c_isvalid = false;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPaletteColor(uint8_t idx, RGBQUAD c)
+{
+ if ((pDib)&&(head.biClrUsed)){
+ uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
+ if (idx<head.biClrUsed){
+ int32_t ldx=idx*sizeof(RGBQUAD);
+ iDst[ldx++] = (uint8_t) c.rgbBlue;
+ iDst[ldx++] = (uint8_t) c.rgbGreen;
+ iDst[ldx++] = (uint8_t) c.rgbRed;
+ iDst[ldx] = (uint8_t) c.rgbReserved;
+ info.last_c_isvalid = false;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPaletteColor(uint8_t idx, COLORREF cr)
+{
+ if ((pDib)&&(head.biClrUsed)){
+ uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
+ if (idx<head.biClrUsed){
+ int32_t ldx=idx*sizeof(RGBQUAD);
+ iDst[ldx++] = (uint8_t) GetBValue(cr);
+ iDst[ldx++] = (uint8_t) GetGValue(cr);
+ iDst[ldx++] = (uint8_t) GetRValue(cr);
+ iDst[ldx] = (uint8_t) 0;
+ info.last_c_isvalid = false;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * returns the pointer to the first palette index
+ */
+RGBQUAD* CxImage::GetPalette() const
+{
+ if ((pDib)&&(head.biClrUsed))
+ return (RGBQUAD*)((uint8_t*)pDib + sizeof(BITMAPINFOHEADER));
+ return NULL;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the color of the specified index.
+ */
+RGBQUAD CxImage::GetPaletteColor(uint8_t idx)
+{
+ RGBQUAD rgb = {0,0,0,0};
+ if ((pDib)&&(head.biClrUsed)){
+ uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
+ if (idx<head.biClrUsed){
+ int32_t ldx=idx*sizeof(RGBQUAD);
+ rgb.rgbBlue = iDst[ldx++];
+ rgb.rgbGreen=iDst[ldx++];
+ rgb.rgbRed =iDst[ldx++];
+ rgb.rgbReserved = iDst[ldx];
+ }
+ }
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the palette index of the specified pixel.
+ */
+uint8_t CxImage::GetPixelIndex(int32_t x,int32_t y)
+{
+ if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
+
+ if ((x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) {
+ if (info.nBkgndIndex >= 0) return (uint8_t)info.nBkgndIndex;
+ else return *info.pImage;
+ }
+ if (head.biBitCount==8){
+ return info.pImage[y*info.dwEffWidth + x];
+ } else {
+ uint8_t pos;
+ uint8_t iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
+ if (head.biBitCount==4){
+ pos = (uint8_t)(4*(1-x%2));
+ iDst &= (0x0F<<pos);
+ return (uint8_t)(iDst >> pos);
+ } else if (head.biBitCount==1){
+ pos = (uint8_t)(7-x%8);
+ iDst &= (0x01<<pos);
+ return (uint8_t)(iDst >> pos);
+ }
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint8_t CxImage::BlindGetPixelIndex(const int32_t x,const int32_t y)
+{
+#ifdef _DEBUG
+ if ((pDib==NULL) || (head.biClrUsed==0) || !IsInside(x,y))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return 0;
+ #endif
+#endif
+
+ if (head.biBitCount==8){
+ return info.pImage[y*info.dwEffWidth + x];
+ } else {
+ uint8_t pos;
+ uint8_t iDst= info.pImage[y*info.dwEffWidth + (x*head.biBitCount >> 3)];
+ if (head.biBitCount==4){
+ pos = (uint8_t)(4*(1-x%2));
+ iDst &= (0x0F<<pos);
+ return (uint8_t)(iDst >> pos);
+ } else if (head.biBitCount==1){
+ pos = (uint8_t)(7-x%8);
+ iDst &= (0x01<<pos);
+ return (uint8_t)(iDst >> pos);
+ }
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::GetPixelColor(int32_t x,int32_t y, bool bGetAlpha)
+{
+// RGBQUAD rgb={0,0,0,0};
+ RGBQUAD rgb=info.nBkgndColor; //<mpwolski>
+ if ((pDib==NULL)||(x<0)||(y<0)||
+ (x>=head.biWidth)||(y>=head.biHeight)){
+ if (info.nBkgndIndex >= 0){
+ if (head.biBitCount<24) return GetPaletteColor((uint8_t)info.nBkgndIndex);
+ else return info.nBkgndColor;
+ } else if (pDib) return GetPixelColor(0,0);
+ return rgb;
+ }
+
+ if (head.biClrUsed){
+ rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
+ } else {
+ uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
+ rgb.rgbBlue = *iDst++;
+ rgb.rgbGreen= *iDst++;
+ rgb.rgbRed = *iDst;
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
+#else
+ rgb.rgbReserved = 0;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * This is (a bit) faster version of GetPixelColor.
+ * It tests bounds only in debug mode (_DEBUG defined).
+ *
+ * It is an error to request out-of-borders pixel with this method.
+ * In DEBUG mode an exception will be thrown, and data will be violated in non-DEBUG mode.
+ * \author ***bd*** 2.2004
+ */
+RGBQUAD CxImage::BlindGetPixelColor(const int32_t x,const int32_t y, bool bGetAlpha)
+{
+ RGBQUAD rgb;
+#ifdef _DEBUG
+ if ((pDib==NULL) || !IsInside(x,y))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ {rgb.rgbReserved = 0; return rgb;}
+ #endif
+#endif
+
+ if (head.biClrUsed){
+ rgb = GetPaletteColor(BlindGetPixelIndex(x,y));
+ } else {
+ uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
+ rgb.rgbBlue = *iDst++;
+ rgb.rgbGreen= *iDst++;
+ rgb.rgbRed = *iDst;
+ rgb.rgbReserved = 0; //needed for images without alpha layer
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha && bGetAlpha) rgb.rgbReserved = BlindAlphaGet(x,y);
+#else
+ rgb.rgbReserved = 0;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ return rgb;
+}
+////////////////////////////////////////////////////////////////////////////////
+uint8_t CxImage::GetPixelGray(int32_t x, int32_t y)
+{
+ RGBQUAD color = GetPixelColor(x,y);
+ return (uint8_t)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::BlindSetPixelIndex(int32_t x,int32_t y,uint8_t i)
+{
+#ifdef _DEBUG
+ if ((pDib==NULL)||(head.biClrUsed==0)||
+ (x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return;
+ #endif
+#endif
+
+ if (head.biBitCount==8){
+ info.pImage[y*info.dwEffWidth + x]=i;
+ return;
+ } else {
+ uint8_t pos;
+ uint8_t* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
+ if (head.biBitCount==4){
+ pos = (uint8_t)(4*(1-x%2));
+ *iDst &= ~(0x0F<<pos);
+ *iDst |= ((i & 0x0F)<<pos);
+ return;
+ } else if (head.biBitCount==1){
+ pos = (uint8_t)(7-x%8);
+ *iDst &= ~(0x01<<pos);
+ *iDst |= ((i & 0x01)<<pos);
+ return;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPixelIndex(int32_t x,int32_t y,uint8_t i)
+{
+ if ((pDib==NULL)||(head.biClrUsed==0)||
+ (x<0)||(y<0)||(x>=head.biWidth)||(y>=head.biHeight)) return ;
+
+ if (head.biBitCount==8){
+ info.pImage[y*info.dwEffWidth + x]=i;
+ return;
+ } else {
+ uint8_t pos;
+ uint8_t* iDst= info.pImage + y*info.dwEffWidth + (x*head.biBitCount >> 3);
+ if (head.biBitCount==4){
+ pos = (uint8_t)(4*(1-x%2));
+ *iDst &= ~(0x0F<<pos);
+ *iDst |= ((i & 0x0F)<<pos);
+ return;
+ } else if (head.biBitCount==1){
+ pos = (uint8_t)(7-x%8);
+ *iDst &= ~(0x01<<pos);
+ *iDst |= ((i & 0x01)<<pos);
+ return;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPixelColor(int32_t x,int32_t y,COLORREF cr)
+{
+ SetPixelColor(x,y,RGBtoRGBQUAD(cr));
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::BlindSetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha)
+{
+#ifdef _DEBUG
+ if ((pDib==NULL)||(x<0)||(y<0)||
+ (x>=head.biWidth)||(y>=head.biHeight))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return;
+ #endif
+#endif
+ if (head.biClrUsed)
+ BlindSetPixelIndex(x,y,GetNearestIndex(c));
+ else {
+ uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
+ *iDst++ = c.rgbBlue;
+ *iDst++ = c.rgbGreen;
+ *iDst = c.rgbRed;
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
+#endif //CXIMAGE_SUPPORT_ALPHA
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPixelColor(int32_t x,int32_t y,RGBQUAD c, bool bSetAlpha)
+{
+ if ((pDib==NULL)||(x<0)||(y<0)||
+ (x>=head.biWidth)||(y>=head.biHeight)) return;
+ if (head.biClrUsed)
+ BlindSetPixelIndex(x,y,GetNearestIndex(c));
+ else {
+ uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
+ *iDst++ = c.rgbBlue;
+ *iDst++ = c.rgbGreen;
+ *iDst = c.rgbRed;
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
+#endif //CXIMAGE_SUPPORT_ALPHA
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Blends the current pixel color with a new color.
+ * \param x,y = pixel
+ * \param c = new color
+ * \param blend = can be from 0 (no effect) to 1 (full effect).
+ * \param bSetAlpha = if true, blends also the alpha component stored in c.rgbReserved
+ */
+void CxImage::BlendPixelColor(int32_t x,int32_t y,RGBQUAD c, float blend, bool bSetAlpha)
+{
+ if ((pDib==NULL)||(x<0)||(y<0)||
+ (x>=head.biWidth)||(y>=head.biHeight)) return;
+
+ int32_t a0 = (int32_t)(256*blend);
+ int32_t a1 = 256 - a0;
+
+ RGBQUAD c0 = BlindGetPixelColor(x,y);
+ c.rgbRed = (uint8_t)((c.rgbRed * a0 + c0.rgbRed * a1)>>8);
+ c.rgbBlue = (uint8_t)((c.rgbBlue * a0 + c0.rgbBlue * a1)>>8);
+ c.rgbGreen = (uint8_t)((c.rgbGreen * a0 + c0.rgbGreen * a1)>>8);
+
+ if (head.biClrUsed)
+ BlindSetPixelIndex(x,y,GetNearestIndex(c));
+ else {
+ uint8_t* iDst = info.pImage + y*info.dwEffWidth + x*3;
+ *iDst++ = c.rgbBlue;
+ *iDst++ = c.rgbGreen;
+ *iDst = c.rgbRed;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (bSetAlpha) AlphaSet(x,y,c.rgbReserved);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the best palette index that matches a specified color.
+ */
+uint8_t CxImage::GetNearestIndex(RGBQUAD c)
+{
+ if ((pDib==NULL)||(head.biClrUsed==0)) return 0;
+
+ // <RJ> check matching with the previous result
+ if (info.last_c_isvalid && (*(int32_t*)&info.last_c == *(int32_t*)&c)) return info.last_c_index;
+ info.last_c = c;
+ info.last_c_isvalid = true;
+
+ uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
+ int32_t distance=200000;
+ int32_t i,j = 0;
+ int32_t k,l;
+ int32_t m = (int32_t)(head.biClrImportant==0 ? head.biClrUsed : head.biClrImportant);
+ for(i=0,l=0;i<m;i++,l+=sizeof(RGBQUAD)){
+ k = (iDst[l]-c.rgbBlue)*(iDst[l]-c.rgbBlue)+
+ (iDst[l+1]-c.rgbGreen)*(iDst[l+1]-c.rgbGreen)+
+ (iDst[l+2]-c.rgbRed)*(iDst[l+2]-c.rgbRed);
+// k = abs(iDst[l]-c.rgbBlue)+abs(iDst[l+1]-c.rgbGreen)+abs(iDst[l+2]-c.rgbRed);
+ if (k==0){
+ j=i;
+ break;
+ }
+ if (k<distance){
+ distance=k;
+ j=i;
+ }
+ }
+ info.last_c_index = (uint8_t)j;
+ return (uint8_t)j;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * swaps the blue and red components (for RGB images)
+ * \param buffer : pointer to the pixels
+ * \param length : number of bytes to swap. lenght may not exceed the scan line.
+ */
+void CxImage::RGBtoBGR(uint8_t *buffer, int32_t length)
+{
+ if (buffer && (head.biClrUsed==0)){
+ uint8_t temp;
+ length = min(length,(int32_t)info.dwEffWidth);
+ length = min(length,(int32_t)(3*head.biWidth));
+ for (int32_t i=0;i<length;i+=3){
+ temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+RGBQUAD CxImage::RGBtoRGBQUAD(COLORREF cr)
+{
+ RGBQUAD c;
+ c.rgbRed = GetRValue(cr); /* get R, G, and B out of uint32_t */
+ c.rgbGreen = GetGValue(cr);
+ c.rgbBlue = GetBValue(cr);
+ c.rgbReserved=0;
+ return c;
+}
+////////////////////////////////////////////////////////////////////////////////
+COLORREF CxImage::RGBQUADtoRGB (RGBQUAD c)
+{
+ return RGB(c.rgbRed,c.rgbGreen,c.rgbBlue);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns the color of the specified index.
+ * \param i = palette index
+ * \param r, g, b = output color channels
+ */
+bool CxImage::GetPaletteColor(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b)
+{
+ RGBQUAD* ppal=GetPalette();
+ if (ppal) {
+ *r = ppal[i].rgbRed;
+ *g = ppal[i].rgbGreen;
+ *b = ppal[i].rgbBlue;
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPalette(uint32_t n, uint8_t *r, uint8_t *g, uint8_t *b)
+{
+ if ((!r)||(pDib==NULL)||(head.biClrUsed==0)) return;
+ if (!g) g = r;
+ if (!b) b = g;
+ RGBQUAD* ppal=GetPalette();
+ uint32_t m=min(n,head.biClrUsed);
+ for (uint32_t i=0; i<m;i++){
+ ppal[i].rgbRed=r[i];
+ ppal[i].rgbGreen=g[i];
+ ppal[i].rgbBlue=b[i];
+ }
+ info.last_c_isvalid = false;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPalette(rgb_color *rgb,uint32_t nColors)
+{
+ if ((!rgb)||(pDib==NULL)||(head.biClrUsed==0)) return;
+ RGBQUAD* ppal=GetPalette();
+ uint32_t m=min(nColors,head.biClrUsed);
+ for (uint32_t i=0; i<m;i++){
+ ppal[i].rgbRed=rgb[i].r;
+ ppal[i].rgbGreen=rgb[i].g;
+ ppal[i].rgbBlue=rgb[i].b;
+ }
+ info.last_c_isvalid = false;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::SetPalette(RGBQUAD* pPal,uint32_t nColors)
+{
+ if ((pPal==NULL)||(pDib==NULL)||(head.biClrUsed==0)) return;
+ memcpy(GetPalette(),pPal,min(GetPaletteSize(),nColors*sizeof(RGBQUAD)));
+ info.last_c_isvalid = false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets (or replaces) the palette to gray scale palette.
+ * The function doesn't change the pixels; for standard
+ * gray scale conversion use GrayScale().
+ */
+void CxImage::SetGrayPalette()
+{
+ if ((pDib==NULL)||(head.biClrUsed==0)) return;
+ RGBQUAD* pal=GetPalette();
+ for (uint32_t ni=0;ni<head.biClrUsed;ni++)
+ pal[ni].rgbBlue=pal[ni].rgbGreen = pal[ni].rgbRed = (uint8_t)(ni*(255/(head.biClrUsed-1)));
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Colorize the palette.
+ * \sa Colorize
+ */
+void CxImage::BlendPalette(COLORREF cr,int32_t perc)
+{
+ if ((pDib==NULL)||(head.biClrUsed==0)) return;
+ uint8_t* iDst = (uint8_t*)(pDib) + sizeof(BITMAPINFOHEADER);
+ uint32_t i,r,g,b;
+ RGBQUAD* pPal=(RGBQUAD*)iDst;
+ r = GetRValue(cr);
+ g = GetGValue(cr);
+ b = GetBValue(cr);
+ if (perc>100) perc=100;
+ for(i=0;i<head.biClrUsed;i++){
+ pPal[i].rgbBlue=(uint8_t)((pPal[i].rgbBlue*(100-perc)+b*perc)/100);
+ pPal[i].rgbGreen =(uint8_t)((pPal[i].rgbGreen*(100-perc)+g*perc)/100);
+ pPal[i].rgbRed =(uint8_t)((pPal[i].rgbRed*(100-perc)+r*perc)/100);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns true if the image has 256 colors and a linear grey scale palette.
+ */
+bool CxImage::IsGrayScale()
+{
+ RGBQUAD* ppal=GetPalette();
+ if(!(pDib && ppal && head.biClrUsed)) return false;
+ for(uint32_t i=0;i<head.biClrUsed;i++){
+ if (ppal[i].rgbBlue!=i || ppal[i].rgbGreen!=i || ppal[i].rgbRed!=i) return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * swap two indexes in the image and their colors in the palette
+ */
+void CxImage::SwapIndex(uint8_t idx1, uint8_t idx2)
+{
+ RGBQUAD* ppal=GetPalette();
+ if(!(pDib && ppal)) return;
+ //swap the colors
+ RGBQUAD tempRGB=GetPaletteColor(idx1);
+ SetPaletteColor(idx1,GetPaletteColor(idx2));
+ SetPaletteColor(idx2,tempRGB);
+ //swap the pixels
+ uint8_t idx;
+ for(int32_t y=0; y < head.biHeight; y++){
+ for(int32_t x=0; x < head.biWidth; x++){
+ idx=BlindGetPixelIndex(x,y);
+ if (idx==idx1) BlindSetPixelIndex(x,y,idx2);
+ if (idx==idx2) BlindSetPixelIndex(x,y,idx1);
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * swap Red and Blue colors
+ */
+void CxImage::SwapRGB2BGR()
+{
+ if (!pDib) return;
+
+ if (head.biClrUsed){
+ RGBQUAD* ppal=GetPalette();
+ uint8_t b;
+ if(!ppal) return;
+ for(uint16_t a=0;a<head.biClrUsed;a++){
+ b=ppal[a].rgbBlue; ppal[a].rgbBlue=ppal[a].rgbRed; ppal[a].rgbRed=b;
+ }
+ } else {
+ for(int32_t y=0;y<head.biHeight;y++){
+ RGBtoBGR(GetBits(y),3*head.biWidth);
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::IsTransparent(int32_t x, int32_t y)
+{
+ if (!pDib) return false;
+
+ if (info.nBkgndIndex>=0){
+ if (head.biClrUsed){
+ if (GetPixelIndex(x,y) == info.nBkgndIndex) return true;
+ } else {
+ RGBQUAD ct = info.nBkgndColor;
+ RGBQUAD c = GetPixelColor(x,y,false);
+ if (*(int32_t*)&c==*(int32_t*)&ct) return true;
+ }
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha) return AlphaGet(x,y)==0;
+#endif
+
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::GetTransparentMask(CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ CxImage tmp;
+ tmp.Create(head.biWidth, head.biHeight, 1, GetType());
+ tmp.SetStdPalette();
+ tmp.Clear(0);
+
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ if (IsTransparent(x,y)){
+ tmp.BlindSetPixelIndex(x,y,1);
+ }
+ }
+ }
+
+ if (iDst) iDst->Transfer(tmp);
+ else Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if image has the same palette, if any.
+ * \param img = image to compare.
+ * \param bCheckAlpha = check also the rgbReserved field.
+ */
+bool CxImage::IsSamePalette(CxImage &img, bool bCheckAlpha)
+{
+ if (head.biClrUsed != img.head.biClrUsed)
+ return false;
+ if (head.biClrUsed == 0)
+ return false;
+
+ RGBQUAD c1,c2;
+ for (uint32_t n=0; n<head.biClrUsed; n++){
+ c1 = GetPaletteColor((uint8_t)n);
+ c2 = img.GetPaletteColor((uint8_t)n);
+ if (c1.rgbRed != c2.rgbRed) return false;
+ if (c1.rgbBlue != c2.rgbBlue) return false;
+ if (c1.rgbGreen != c2.rgbGreen) return false;
+ if (bCheckAlpha && (c1.rgbReserved != c2.rgbReserved)) return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa SetClrImportant
+ */
+uint32_t CxImage::GetClrImportant() const
+{
+ return head.biClrImportant;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * sets the maximum number of colors that some functions like
+ * DecreaseBpp() or GetNearestIndex() will use on indexed images
+ * \param ncolors should be less than 2^bpp,
+ * or 0 if all the colors are important.
+ */
+void CxImage::SetClrImportant(uint32_t ncolors)
+{
+ if (ncolors==0 || ncolors>256) {
+ head.biClrImportant = 0;
+ return;
+ }
+
+ switch(head.biBitCount){
+ case 1:
+ head.biClrImportant = min(ncolors,2);
+ break;
+ case 4:
+ head.biClrImportant = min(ncolors,16);
+ break;
+ case 8:
+ head.biClrImportant = ncolors;
+ break;
+ }
+ return;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns pointer to pixel. Currently implemented only for truecolor images.
+ *
+ * \param x,y - coordinates
+ *
+ * \return pointer to first byte of pixel data
+ *
+ * \author ***bd*** 2.2004
+ */
+void* CxImage::BlindGetPixelPointer(const int32_t x, const int32_t y)
+{
+#ifdef _DEBUG
+ if ((pDib==NULL) || !IsInside(x,y))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return 0;
+ #endif
+#endif
+ if (!IsIndexed())
+ return info.pImage + y*info.dwEffWidth + x*3;
+ else
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, COLORREF cr)
+{
+ DrawLine(StartX, EndX, StartY, EndY, RGBtoRGBQUAD(cr));
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImage::DrawLine(int32_t StartX, int32_t EndX, int32_t StartY, int32_t EndY, RGBQUAD color, bool bSetAlpha)
+{
+ if (!pDib) return;
+ //////////////////////////////////////////////////////
+ // Draws a line using the Bresenham line algorithm
+ // Thanks to Jordan DeLozier <JDL>
+ //////////////////////////////////////////////////////
+ int32_t x1 = StartX;
+ int32_t y1 = StartY;
+ int32_t x = x1; // Start x off at the first pixel
+ int32_t y = y1; // Start y off at the first pixel
+ int32_t x2 = EndX;
+ int32_t y2 = EndY;
+
+ int32_t xinc1,xinc2,yinc1,yinc2; // Increasing values
+ int32_t den, num, numadd,numpixels;
+ int32_t deltax = abs(x2 - x1); // The difference between the x's
+ int32_t deltay = abs(y2 - y1); // The difference between the y's
+
+ // Get Increasing Values
+ if (x2 >= x1) { // The x-values are increasing
+ xinc1 = 1;
+ xinc2 = 1;
+ } else { // The x-values are decreasing
+ xinc1 = -1;
+ xinc2 = -1;
+ }
+
+ if (y2 >= y1) { // The y-values are increasing
+ yinc1 = 1;
+ yinc2 = 1;
+ } else { // The y-values are decreasing
+ yinc1 = -1;
+ yinc2 = -1;
+ }
+
+ // Actually draw the line
+ if (deltax >= deltay) // There is at least one x-value for every y-value
+ {
+ xinc1 = 0; // Don't change the x when numerator >= denominator
+ yinc2 = 0; // Don't change the y for every iteration
+ den = deltax;
+ num = deltax / 2;
+ numadd = deltay;
+ numpixels = deltax; // There are more x-values than y-values
+ }
+ else // There is at least one y-value for every x-value
+ {
+ xinc2 = 0; // Don't change the x for every iteration
+ yinc1 = 0; // Don't change the y when numerator >= denominator
+ den = deltay;
+ num = deltay / 2;
+ numadd = deltax;
+ numpixels = deltay; // There are more y-values than x-values
+ }
+
+ for (int32_t curpixel = 0; curpixel <= numpixels; curpixel++)
+ {
+ // Draw the current pixel
+ SetPixelColor(x,y,color,bSetAlpha);
+
+ num += numadd; // Increase the numerator by the top of the fraction
+ if (num >= den) // Check if numerator >= denominator
+ {
+ num -= den; // Calculate the new numerator value
+ x += xinc1; // Change the x as appropriate
+ y += yinc1; // Change the y as appropriate
+ }
+ x += xinc2; // Change the x as appropriate
+ y += yinc2; // Change the y as appropriate
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets a palette with standard colors for 1, 4 and 8 bpp images.
+ */
+void CxImage::SetStdPalette()
+{
+ if (!pDib) return;
+ switch (head.biBitCount){
+ case 8:
+ {
+ const uint8_t pal256[1024] = {0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
+ 192,220,192,0,240,202,166,0,212,240,255,0,177,226,255,0,142,212,255,0,107,198,255,0,
+ 72,184,255,0,37,170,255,0,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,
+ 50,80,0,212,227,255,0,177,199,255,0,142,171,255,0,107,143,255,0,72,115,255,0,37,87,255,0,0,
+ 85,255,0,0,73,220,0,0,61,185,0,0,49,150,0,0,37,115,0,0,25,80,0,212,212,255,0,177,177,255,0,
+ 142,142,255,0,107,107,255,0,72,72,255,0,37,37,255,0,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,
+ 0,0,115,0,0,0,80,0,227,212,255,0,199,177,255,0,171,142,255,0,143,107,255,0,115,72,255,0,
+ 87,37,255,0,85,0,255,0,73,0,220,0,61,0,185,0,49,0,150,0,37,0,115,0,25,0,80,0,240,212,255,0,
+ 226,177,255,0,212,142,255,0,198,107,255,0,184,72,255,0,170,37,255,0,170,0,255,0,146,0,220,0,
+ 122,0,185,0,98,0,150,0,74,0,115,0,50,0,80,0,255,212,255,0,255,177,255,0,255,142,255,0,255,107,255,0,
+ 255,72,255,0,255,37,255,0,254,0,254,0,220,0,220,0,185,0,185,0,150,0,150,0,115,0,115,0,80,0,80,0,
+ 255,212,240,0,255,177,226,0,255,142,212,0,255,107,198,0,255,72,184,0,255,37,170,0,255,0,170,0,
+ 220,0,146,0,185,0,122,0,150,0,98,0,115,0,74,0,80,0,50,0,255,212,227,0,255,177,199,0,255,142,171,0,
+ 255,107,143,0,255,72,115,0,255,37,87,0,255,0,85,0,220,0,73,0,185,0,61,0,150,0,49,0,115,0,37,0,
+ 80,0,25,0,255,212,212,0,255,177,177,0,255,142,142,0,255,107,107,0,255,72,72,0,255,37,37,0,254,0,
+ 0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,0,255,227,212,0,255,199,177,0,255,171,142,0,
+ 255,143,107,0,255,115,72,0,255,87,37,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,115,37,0,
+ 0,80,25,0,0,255,240,212,0,255,226,177,0,255,212,142,0,255,198,107,0,255,184,72,0,255,170,37,0,
+ 255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,0,255,255,212,0,255,255,177,0,
+ 255,255,142,0,255,255,107,0,255,255,72,0,255,255,37,0,254,254,0,0,220,220,0,0,185,185,0,0,150,150,0,
+ 0,115,115,0,0,80,80,0,0,240,255,212,0,226,255,177,0,212,255,142,0,198,255,107,0,184,255,72,0,
+ 170,255,37,0,170,255,0,0,146,220,0,0,122,185,0,0,98,150,0,0,74,115,0,0,50,80,0,0,227,255,212,0,
+ 199,255,177,0,171,255,142,0,143,255,107,0,115,255,72,0,87,255,37,0,85,255,0,0,73,220,0,0,61,185,0,
+ 0,49,150,0,0,37,115,0,0,25,80,0,0,212,255,212,0,177,255,177,0,142,255,142,0,107,255,107,0,72,255,72,0,
+ 37,255,37,0,0,254,0,0,0,220,0,0,0,185,0,0,0,150,0,0,0,115,0,0,0,80,0,0,212,255,227,0,177,255,199,0,
+ 142,255,171,0,107,255,143,0,72,255,115,0,37,255,87,0,0,255,85,0,0,220,73,0,0,185,61,0,0,150,49,0,0,
+ 115,37,0,0,80,25,0,212,255,240,0,177,255,226,0,142,255,212,0,107,255,198,0,72,255,184,0,37,255,170,0,
+ 0,255,170,0,0,220,146,0,0,185,122,0,0,150,98,0,0,115,74,0,0,80,50,0,212,255,255,0,177,255,255,0,
+ 142,255,255,0,107,255,255,0,72,255,255,0,37,255,255,0,0,254,254,0,0,220,220,0,0,185,185,0,0,
+ 150,150,0,0,115,115,0,0,80,80,0,242,242,242,0,230,230,230,0,218,218,218,0,206,206,206,0,194,194,194,0,
+ 182,182,182,0,170,170,170,0,158,158,158,0,146,146,146,0,134,134,134,0,122,122,122,0,110,110,110,0,
+ 98,98,98,0,86,86,86,0,74,74,74,0,62,62,62,0,50,50,50,0,38,38,38,0,26,26,26,0,14,14,14,0,240,251,255,0,
+ 164,160,160,0,128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
+ memcpy(GetPalette(),pal256,1024);
+ break;
+ }
+ case 4:
+ {
+ const uint8_t pal16[64]={0,0,0,0,0,0,128,0,0,128,0,0,0,128,128,0,128,0,0,0,128,0,128,0,128,128,0,0,192,192,192,0,
+ 128,128,128,0,0,0,255,0,0,255,0,0,0,255,255,0,255,0,0,0,255,0,255,0,255,255,0,0,255,255,255,0};
+ memcpy(GetPalette(),pal16,64);
+ break;
+ }
+ case 1:
+ {
+ const uint8_t pal2[8]={0,0,0,0,255,255,255,0};
+ memcpy(GetPalette(),pal2,8);
+ break;
+ }
+ }
+ info.last_c_isvalid = false;
+ return;
+}
+////////////////////////////////////////////////////////////////////////////////
diff --git a/archive/hge/CxImage/ximapcx.cpp b/archive/hge/CxImage/ximapcx.cpp new file mode 100644 index 0000000..2fa2f5d --- /dev/null +++ b/archive/hge/CxImage/ximapcx.cpp @@ -0,0 +1,479 @@ +/*
+ * File: ximapcx.cpp
+ * Purpose: Platform Independent PCX Image Class Loader and Writer
+ * 05/Jan/2002 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ *
+ * based on ppmtopcx.c - convert a portable pixmap to PCX
+ * Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
+ * based on ppmtopcx.c by Michael Davidson
+ */
+
+#include "ximapcx.h"
+
+#if CXIMAGE_SUPPORT_PCX
+
+#include "xmemfile.h"
+
+#define PCX_MAGIC 0X0A // PCX magic number
+#define PCX_256_COLORS 0X0C // magic number for 256 colors
+#define PCX_HDR_SIZE 128 // size of PCX header
+#define PCX_MAXCOLORS 256
+#define PCX_MAXPLANES 4
+#define PCX_MAXVAL 255
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImagePCX::Decode(CxFile *hFile)
+{
+ if (hFile == NULL) return false;
+
+ PCXHEADER pcxHeader;
+ int32_t i, x, y, y2, nbytes, count, Height, Width;
+ uint8_t c, ColorMap[PCX_MAXCOLORS][3];
+ uint8_t *pcximage = NULL, *lpHead1 = NULL, *lpHead2 = NULL;
+ uint8_t *pcxplanes, *pcxpixels;
+
+ cx_try
+ {
+ if (hFile->Read(&pcxHeader,sizeof(PCXHEADER),1)==0) cx_throw("Can't read PCX image");
+
+ PCX_toh(&pcxHeader);
+
+ if (pcxHeader.Manufacturer != PCX_MAGIC) cx_throw("Error: Not a PCX file");
+ // Check for PCX run length encoding
+ if (pcxHeader.Encoding != 1) cx_throw("PCX file has unknown encoding scheme");
+
+ Width = (pcxHeader.Xmax - pcxHeader.Xmin) + 1;
+ Height = (pcxHeader.Ymax - pcxHeader.Ymin) + 1;
+ info.xDPI = pcxHeader.Hres;
+ info.yDPI = pcxHeader.Vres;
+
+ if (info.nEscape == -1){
+ head.biWidth = Width;
+ head.biHeight= Height;
+ info.dwType = CXIMAGE_FORMAT_PCX;
+ return true;
+ }
+
+ // Check that we can handle this image format
+ if (pcxHeader.ColorPlanes > 4)
+ cx_throw("Can't handle image with more than 4 planes");
+
+ // Create the image
+ if (pcxHeader.ColorPlanes >= 3 && pcxHeader.BitsPerPixel == 8){
+ Create (Width, Height, 24, CXIMAGE_FORMAT_PCX);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pcxHeader.ColorPlanes==4) AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+ } else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 1)
+ Create (Width, Height, 4, CXIMAGE_FORMAT_PCX);
+ else
+ Create (Width, Height, pcxHeader.BitsPerPixel, CXIMAGE_FORMAT_PCX);
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ //Read the image and check if it's ok
+ nbytes = pcxHeader.BytesPerLine * pcxHeader.ColorPlanes * Height;
+ lpHead1 = pcximage = (uint8_t*)malloc(nbytes);
+ while (nbytes > 0){
+ if (hFile == NULL || hFile->Eof()) cx_throw("corrupted PCX");
+
+ hFile->Read(&c,1,1);
+ if ((c & 0XC0) != 0XC0){ // Repeated group
+ *pcximage++ = c;
+ --nbytes;
+ continue;
+ }
+ count = c & 0X3F; // extract count
+ hFile->Read(&c,1,1);
+ if (count > nbytes) cx_throw("repeat count spans end of image");
+
+ nbytes -= count;
+ while (--count >=0) *pcximage++ = c;
+ }
+ pcximage = lpHead1;
+
+ //store the palette
+ for (i = 0; i < 16; i++){
+ ColorMap[i][0] = pcxHeader.ColorMap[i][0];
+ ColorMap[i][1] = pcxHeader.ColorMap[i][1];
+ ColorMap[i][2] = pcxHeader.ColorMap[i][2];
+ }
+ if (pcxHeader.BitsPerPixel == 8 && pcxHeader.ColorPlanes == 1){
+ hFile->Read(&c,1,1);
+ if (c != PCX_256_COLORS) cx_throw("bad color map signature");
+
+ for (i = 0; i < PCX_MAXCOLORS; i++){
+ hFile->Read(&ColorMap[i][0],1,1);
+ hFile->Read(&ColorMap[i][1],1,1);
+ hFile->Read(&ColorMap[i][2],1,1);
+ }
+ }
+ if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
+ ColorMap[0][0] = ColorMap[0][1] = ColorMap[0][2] = 0;
+ ColorMap[1][0] = ColorMap[1][1] = ColorMap[1][2] = 255;
+ }
+
+ for (uint32_t idx=0; idx<head.biClrUsed; idx++) SetPaletteColor((uint8_t)idx,ColorMap[idx][0],ColorMap[idx][1],ColorMap[idx][2]);
+
+ lpHead2 = pcxpixels = (uint8_t *)malloc(Width + pcxHeader.BytesPerLine * 8);
+ // Convert the image
+ for (y = 0; y < Height; y++){
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ y2=Height-1-y;
+ pcxpixels = lpHead2;
+ pcxplanes = pcximage + (y * pcxHeader.BytesPerLine * pcxHeader.ColorPlanes);
+
+ if (pcxHeader.ColorPlanes == 3 && pcxHeader.BitsPerPixel == 8){
+ // Deal with 24 bit color image
+ for (x = 0; x < Width; x++){
+ SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
+ }
+ continue;
+#if CXIMAGE_SUPPORT_ALPHA
+ } else if (pcxHeader.ColorPlanes == 4 && pcxHeader.BitsPerPixel == 8){
+ for (x = 0; x < Width; x++){
+ SetPixelColor(x,y2,RGB(pcxplanes[x],pcxplanes[pcxHeader.BytesPerLine + x],pcxplanes[2*pcxHeader.BytesPerLine + x]));
+ AlphaSet(x,y2,pcxplanes[3*pcxHeader.BytesPerLine + x]);
+ }
+ continue;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ } else if (pcxHeader.ColorPlanes == 1) {
+ if (!PCX_UnpackPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
+ cx_throw("PCX_UnpackPixels: Can't handle packed pixels with more than 1 plane");
+ }
+ } else {
+ if (!PCX_PlanesToPixels(pcxpixels, pcxplanes, pcxHeader.BytesPerLine, pcxHeader.ColorPlanes, pcxHeader.BitsPerPixel)){
+ cx_throw("PCX_PlanesToPixels: more than 4 planes or more than 1 bit per pixel");
+ }
+ }
+ for (x = 0; x < Width; x++) SetPixelIndex(x,y2,pcxpixels[x]);
+ }
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (lpHead1){ free(lpHead1); lpHead1 = NULL; }
+ if (lpHead2){ free(lpHead2); lpHead2 = NULL; }
+ return false;
+ }
+ if (lpHead1){ free(lpHead1); lpHead1 = NULL; }
+ if (lpHead2){ free(lpHead2); lpHead2 = NULL; }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImagePCX::Encode(CxFile * hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ cx_try
+ {
+ PCXHEADER pcxHeader;
+ memset(&pcxHeader,0,sizeof(pcxHeader));
+ pcxHeader.Manufacturer = PCX_MAGIC;
+ pcxHeader.Version = 5;
+ pcxHeader.Encoding = 1;
+ pcxHeader.Xmin = 0;
+ pcxHeader.Ymin = 0;
+ pcxHeader.Xmax = (uint16_t)head.biWidth-1;
+ pcxHeader.Ymax = (uint16_t)head.biHeight-1;
+ pcxHeader.Hres = (uint16_t)info.xDPI;
+ pcxHeader.Vres = (uint16_t)info.yDPI;
+ pcxHeader.Reserved = 0;
+ pcxHeader.PaletteType = head.biClrUsed==0;
+
+ switch(head.biBitCount){
+ case 24:
+ case 8:
+ {
+ pcxHeader.BitsPerPixel = 8;
+ pcxHeader.ColorPlanes = head.biClrUsed==0 ? 3 : 1;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid() && head.biClrUsed==0) pcxHeader.ColorPlanes =4;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ pcxHeader.BytesPerLine = (uint16_t)head.biWidth;
+ break;
+ }
+ default: //(4 1)
+ pcxHeader.BitsPerPixel = 1;
+ pcxHeader.ColorPlanes = head.biClrUsed==16 ? 4 : 1;
+ pcxHeader.BytesPerLine = (uint16_t)((head.biWidth * pcxHeader.BitsPerPixel + 7)>>3);
+ }
+
+ if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 1){
+ pcxHeader.ColorMap[0][0] = pcxHeader.ColorMap[0][1] = pcxHeader.ColorMap[0][2] = 0;
+ pcxHeader.ColorMap[1][0] = pcxHeader.ColorMap[1][1] = pcxHeader.ColorMap[1][2] = 255;
+ }
+ if (pcxHeader.BitsPerPixel == 1 && pcxHeader.ColorPlanes == 4){
+ RGBQUAD c;
+ for (int32_t i = 0; i < 16; i++){
+ c=GetPaletteColor(i);
+ pcxHeader.ColorMap[i][0] = c.rgbRed;
+ pcxHeader.ColorMap[i][1] = c.rgbGreen;
+ pcxHeader.ColorMap[i][2] = c.rgbBlue;
+ }
+ }
+
+ pcxHeader.BytesPerLine = (pcxHeader.BytesPerLine + 1)&(~1);
+
+ PCX_toh(&pcxHeader);
+ if (hFile->Write(&pcxHeader, sizeof(pcxHeader), 1) == 0 )
+ cx_throw("cannot write PCX header");
+ PCX_toh(&pcxHeader);
+
+ CxMemFile buffer;
+ buffer.Open();
+
+ uint8_t c,n;
+ int32_t x,y;
+ if (head.biClrUsed==0){
+ for (y = head.biHeight-1; y >=0 ; y--){
+ for (int32_t p=0; p<pcxHeader.ColorPlanes; p++){
+ c=n=0;
+ for (x = 0; x<head.biWidth; x++){
+ if (p==0)
+ PCX_PackPixels(BlindGetPixelColor(x,y).rgbRed,c,n,buffer);
+ else if (p==1)
+ PCX_PackPixels(BlindGetPixelColor(x,y).rgbGreen,c,n,buffer);
+ else if (p==2)
+ PCX_PackPixels(BlindGetPixelColor(x,y).rgbBlue,c,n,buffer);
+#if CXIMAGE_SUPPORT_ALPHA
+ else if (p==3)
+ PCX_PackPixels(BlindAlphaGet(x,y),c,n,buffer);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
+ }
+ }
+
+ hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
+
+ } else if (head.biBitCount==8) {
+
+ for (y = head.biHeight-1; y >=0 ; y--){
+ c=n=0;
+ for (x = 0; x<head.biWidth; x++){
+ PCX_PackPixels(GetPixelIndex(x,y),c,n,buffer);
+ }
+ PCX_PackPixels(-1-(head.biWidth&0x1),c,n,buffer);
+ }
+
+ hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
+
+ if (head.biBitCount == 8){
+ hFile->PutC(0x0C);
+ uint8_t* pal = (uint8_t*)malloc(768);
+ RGBQUAD c;
+ for (int32_t i=0;i<256;i++){
+ c=GetPaletteColor(i);
+ pal[3*i+0] = c.rgbRed;
+ pal[3*i+1] = c.rgbGreen;
+ pal[3*i+2] = c.rgbBlue;
+ }
+ hFile->Write(pal,768,1);
+ free(pal);
+ }
+ } else { //(head.biBitCount==4) || (head.biBitCount==1)
+
+ RGBQUAD *rgb = GetPalette();
+ bool binvert = false;
+ if (CompareColors(&rgb[0],&rgb[1])>0) binvert=(head.biBitCount==1);
+
+ uint8_t* plane = (uint8_t*)malloc(pcxHeader.BytesPerLine);
+ uint8_t* raw = (uint8_t*)malloc(head.biWidth);
+
+ for(y = head.biHeight-1; y >=0 ; y--) {
+
+ for( x = 0; x < head.biWidth; x++) raw[x] = (uint8_t)GetPixelIndex(x,y);
+
+ if (binvert) for( x = 0; x < head.biWidth; x++) raw[x] = 1-raw[x];
+
+ for( x = 0; x < pcxHeader.ColorPlanes; x++ ) {
+ PCX_PixelsToPlanes(raw, head.biWidth, plane, x);
+ PCX_PackPlanes(plane, pcxHeader.BytesPerLine, buffer);
+ }
+ }
+
+ free(plane);
+ free(raw);
+
+ hFile->Write(buffer.GetBuffer(false),buffer.Tell(),1);
+
+ }
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+// Convert multi-plane format into 1 pixel per byte
+// from unpacked file data bitplanes[] into pixel row pixels[]
+// image Height rows, with each row having planes image planes each
+// bytesperline bytes
+bool CxImagePCX::PCX_PlanesToPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel)
+{
+ int32_t i, j, npixels;
+ uint8_t * p;
+ if (planes > 4) return false;
+ if (bitsperpixel != 1) return false;
+
+ // Clear the pixel buffer
+ npixels = (bytesperline * 8) / bitsperpixel;
+ p = pixels;
+ while (--npixels >= 0) *p++ = 0;
+
+ // Do the format conversion
+ for (i = 0; i < planes; i++){
+ int32_t pixbit, bits, mask;
+ p = pixels;
+ pixbit = (1 << i); // pixel bit for this plane
+ for (j = 0; j < bytesperline; j++){
+ bits = *bitplanes++;
+ for (mask = 0X80; mask != 0; mask >>= 1, p++)
+ if (bits & mask) *p |= pixbit;
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+// convert packed pixel format into 1 pixel per byte
+// from unpacked file data bitplanes[] into pixel row pixels[]
+// image Height rows, with each row having planes image planes each
+// bytesperline bytes
+bool CxImagePCX::PCX_UnpackPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel)
+{
+ register int32_t bits;
+ if (planes != 1) return false;
+
+ if (bitsperpixel == 8){ // 8 bits/pixels, no unpacking needed
+ while (bytesperline-- > 0) *pixels++ = *bitplanes++;
+ } else if (bitsperpixel == 4){ // 4 bits/pixel, two pixels per byte
+ while (bytesperline-- > 0){
+ bits = *bitplanes++;
+ *pixels++ = (uint8_t)((bits >> 4) & 0X0F);
+ *pixels++ = (uint8_t)((bits) & 0X0F);
+ }
+ } else if (bitsperpixel == 2){ // 2 bits/pixel, four pixels per byte
+ while (bytesperline-- > 0){
+ bits = *bitplanes++;
+ *pixels++ = (uint8_t)((bits >> 6) & 0X03);
+ *pixels++ = (uint8_t)((bits >> 4) & 0X03);
+ *pixels++ = (uint8_t)((bits >> 2) & 0X03);
+ *pixels++ = (uint8_t)((bits) & 0X03);
+ }
+ } else if (bitsperpixel == 1){ // 1 bits/pixel, 8 pixels per byte
+ while (bytesperline-- > 0){
+ bits = *bitplanes++;
+ *pixels++ = ((bits & 0X80) != 0);
+ *pixels++ = ((bits & 0X40) != 0);
+ *pixels++ = ((bits & 0X20) != 0);
+ *pixels++ = ((bits & 0X10) != 0);
+ *pixels++ = ((bits & 0X08) != 0);
+ *pixels++ = ((bits & 0X04) != 0);
+ *pixels++ = ((bits & 0X02) != 0);
+ *pixels++ = ((bits & 0X01) != 0);
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/* PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, int32_t &l, CxFile &f)
+ * p = current pixel (-1 ends the line -2 ends odd line)
+ * c = previous pixel
+ * n = number of consecutive pixels
+ */
+void CxImagePCX::PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, CxFile &f)
+{
+ if (p!=c && n){
+ if (n==1 && c<0xC0){
+ f.PutC(c);
+ } else {
+ f.PutC(0xC0|n);
+ f.PutC(c);
+ }
+ n=0;
+ }
+ if (n==0x3F) {
+ f.PutC(0xFF);
+ f.PutC(c);
+ n=0;
+ }
+ if (p==-2) f.PutC(0);
+ c=(uint8_t)p;
+ n++;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImagePCX::PCX_PackPlanes(uint8_t* buff, const int32_t size, CxFile &f)
+{
+ uint8_t *start,*end;
+ uint8_t c, previous, count;
+
+ start = buff;
+ end = buff + size;
+ previous = *start++;
+ count = 1;
+
+ while (start < end) {
+ c = *start++;
+ if (c == previous && count < 63) {
+ ++count;
+ continue;
+ }
+
+ if (count > 1 || (previous & 0xc0) == 0xc0) {
+ f.PutC( count | 0xc0 );
+ }
+ f.PutC(previous);
+ previous = c;
+ count = 1;
+ }
+
+ if (count > 1 || (previous & 0xc0) == 0xc0) {
+ count |= 0xc0;
+ f.PutC(count);
+ }
+ f.PutC(previous);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImagePCX::PCX_PixelsToPlanes(uint8_t* raw, int32_t width, uint8_t* buf, int32_t plane)
+{
+ int32_t cbit, x, mask;
+ uint8_t *cp = buf-1;
+
+ mask = 1 << plane;
+ cbit = -1;
+ for( x = 0; x < width; x++ ) {
+ if( cbit < 0 ) {
+ cbit = 7;
+ *++cp = 0;
+ }
+ if( raw[x] & mask )
+ *cp |= (1<<cbit);
+ --cbit;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImagePCX::PCX_toh(PCXHEADER* p)
+{
+ p->Xmin = m_ntohs(p->Xmin);
+ p->Ymin = m_ntohs(p->Ymin);
+ p->Xmax = m_ntohs(p->Xmax);
+ p->Ymax = m_ntohs(p->Ymax);
+ p->Hres = m_ntohs(p->Hres);
+ p->Vres = m_ntohs(p->Vres);
+ p->BytesPerLine = m_ntohs(p->BytesPerLine);
+ p->PaletteType = m_ntohs(p->PaletteType);
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_PCX
diff --git a/archive/hge/CxImage/ximapcx.h b/archive/hge/CxImage/ximapcx.h new file mode 100644 index 0000000..05c5ad0 --- /dev/null +++ b/archive/hge/CxImage/ximapcx.h @@ -0,0 +1,64 @@ +/*
+ * File: ximapcx.h
+ * Purpose: PCX Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImagePCX (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Parts of the code come from Paintlib: Copyright (c) 1996-1998 Ulrich von Zadow
+ * ==========================================================
+ */
+#if !defined(__ximaPCX_h)
+#define __ximaPCX_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_PCX
+
+class CxImagePCX: public CxImage
+{
+// PCX Image File
+#pragma pack(1)
+typedef struct tagPCXHEADER
+{
+ char Manufacturer; // always 0X0A
+ char Version; // version number
+ char Encoding; // always 1
+ char BitsPerPixel; // color bits
+ uint16_t Xmin, Ymin; // image origin
+ uint16_t Xmax, Ymax; // image dimensions
+ uint16_t Hres, Vres; // resolution values
+ uint8_t ColorMap[16][3]; // color palette
+ char Reserved;
+ char ColorPlanes; // color planes
+ uint16_t BytesPerLine; // line buffer size
+ uint16_t PaletteType; // grey or color palette
+ char Filter[58];
+} PCXHEADER;
+#pragma pack()
+
+public:
+ CxImagePCX(): CxImage(CXIMAGE_FORMAT_PCX) {}
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PCX);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PCX);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+protected:
+ bool PCX_PlanesToPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel);
+ bool PCX_UnpackPixels(uint8_t * pixels, uint8_t * bitplanes, int16_t bytesperline, int16_t planes, int16_t bitsperpixel);
+ void PCX_PackPixels(const int32_t p,uint8_t &c, uint8_t &n, CxFile &f);
+ void PCX_PackPlanes(uint8_t* buff, const int32_t size, CxFile &f);
+ void PCX_PixelsToPlanes(uint8_t* raw, int32_t width, uint8_t* buf, int32_t plane);
+ void PCX_toh(PCXHEADER* p);
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximapng.cpp b/archive/hge/CxImage/ximapng.cpp new file mode 100644 index 0000000..db2f636 --- /dev/null +++ b/archive/hge/CxImage/ximapng.cpp @@ -0,0 +1,644 @@ +/*
+ * File: ximapng.cpp
+ * Purpose: Platform Independent PNG Image Class Loader and Writer
+ * 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximapng.h"
+
+#if CXIMAGE_SUPPORT_PNG
+
+#include "ximaiter.h"
+
+////////////////////////////////////////////////////////////////////////////////
+void CxImagePNG::ima_png_error(png_struct *png_ptr, char *message)
+{
+ strcpy(info.szLastError,message);
+#if PNG_LIBPNG_VER > 10399
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+void CxImagePNG::expand2to4bpp(uint8_t* prow)
+{
+ uint8_t *psrc,*pdst;
+ uint8_t pos,idx;
+ for(int32_t x=head.biWidth-1;x>=0;x--){
+ psrc = prow + ((2*x)>>3);
+ pdst = prow + ((4*x)>>3);
+ pos = (uint8_t)(2*(3-x%4));
+ idx = (uint8_t)((*psrc & (0x03<<pos))>>pos);
+ pos = (uint8_t)(4*(1-x%2));
+ *pdst &= ~(0x0F<<pos);
+ *pdst |= (idx & 0x0F)<<pos;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImagePNG::Decode(CxFile *hFile)
+{
+ png_struct *png_ptr;
+ png_info *info_ptr;
+ uint8_t *row_pointers=NULL;
+ CImageIterator iter(this);
+
+ cx_try
+ {
+ /* Create and initialize the png_struct with the desired error handler
+ * functions. If you want to use the default stderr and longjump method,
+ * you can supply NULL for the last three parameters. We also supply the
+ * the compiler header file version, so that we know if the application
+ * was compiled with a compatible version of the library. REQUIRED */
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,(void *)NULL,NULL,NULL);
+ if (png_ptr == NULL) cx_throw("Failed to create PNG structure");
+
+ /* Allocate/initialize the memory for image information. REQUIRED. */
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+ cx_throw("Failed to initialize PNG info structure");
+ }
+
+ /* Set error handling if you are using the setjmp/longjmp method (this is
+ * the normal method of doing things with libpng). REQUIRED unless you
+ * set up your own error handlers in the png_create_read_struct() earlier. */
+#if PNG_LIBPNG_VER > 10399
+ if (setjmp(png_jmpbuf(png_ptr))) {
+#else
+ if (setjmp(png_ptr->jmpbuf)) {
+#endif
+ /* Free all of the memory associated with the png_ptr and info_ptr */
+ delete [] row_pointers;
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+ cx_throw("");
+ }
+
+ // use custom I/O functions
+ png_set_read_fn(png_ptr, hFile, /*(png_rw_ptr)*/user_read_data);
+ png_set_error_fn(png_ptr,info.szLastError,/*(png_error_ptr)*/user_error_fn,NULL);
+
+ /* read the file information */
+ png_read_info(png_ptr, info_ptr);
+
+ png_uint_32 _width,_height;
+ int _bit_depth,_color_type,_interlace_type,_compression_type,_filter_type;
+#if PNG_LIBPNG_VER > 10399
+ png_get_IHDR(png_ptr,info_ptr,&_width,&_height,&_bit_depth,&_color_type,
+ &_interlace_type,&_compression_type,&_filter_type);
+#else
+ _width=info_ptr->width;
+ _height=info_ptr->height;
+ _bit_depth=info_ptr->bit_depth;
+ _color_type=info_ptr->color_type;
+ _interlace_type=info_ptr->interlace_type;
+ //_compression_type=info_ptr->compression_type;
+ //_filter_type=info_ptr->filter_type;
+#endif
+
+ if (info.nEscape == -1){
+ head.biWidth = _width;
+ head.biHeight= _height;
+ info.dwType = CXIMAGE_FORMAT_PNG;
+#if PNG_LIBPNG_VER > 10399
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+ }
+
+ /* calculate new number of channels */
+ int32_t channels=0;
+ switch(_color_type){
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_PALETTE:
+ channels = 1;
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ channels = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ channels = 3;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ channels = 4;
+ break;
+ default:
+ strcpy(info.szLastError,"unknown PNG color type");
+#if PNG_LIBPNG_VER > 10399
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+ }
+
+ //find the right pixel depth used for cximage
+#if PNG_LIBPNG_VER > 10399
+ int pixel_depth = _bit_depth * png_get_channels(png_ptr,info_ptr);
+#else
+ int pixel_depth = info_ptr->pixel_depth;
+#endif
+ if (channels == 1 && pixel_depth>8) pixel_depth=8;
+ if (channels == 2) pixel_depth=8;
+ if (channels >= 3) pixel_depth=24;
+
+ if (!Create(_width, _height, pixel_depth, CXIMAGE_FORMAT_PNG)){
+#if PNG_LIBPNG_VER > 10399
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+ }
+
+ /* get metrics */
+ png_uint_32 _x_pixels_per_unit,_y_pixels_per_unit;
+ int _phys_unit_type;
+#if PNG_LIBPNG_VER > 10399
+ png_get_pHYs(png_ptr,info_ptr,&_x_pixels_per_unit,&_y_pixels_per_unit,&_phys_unit_type);
+#else
+ _x_pixels_per_unit=info_ptr->x_pixels_per_unit;
+ _y_pixels_per_unit=info_ptr->y_pixels_per_unit;
+ _phys_unit_type=info_ptr->phys_unit_type;
+#endif
+ switch (_phys_unit_type)
+ {
+ case PNG_RESOLUTION_UNKNOWN:
+ SetXDPI(_x_pixels_per_unit);
+ SetYDPI(_y_pixels_per_unit);
+ break;
+ case PNG_RESOLUTION_METER:
+ SetXDPI((long)floor(_x_pixels_per_unit * 254.0 / 10000.0 + 0.5));
+ SetYDPI((long)floor(_y_pixels_per_unit * 254.0 / 10000.0 + 0.5));
+ break;
+ }
+
+ int _num_palette;
+ png_colorp _palette;
+#if PNG_LIBPNG_VER > 10399
+ png_get_PLTE(png_ptr,info_ptr,&_palette,&_num_palette);
+#else
+ _num_palette=info_ptr->num_palette;
+ _palette=info_ptr->palette;
+#endif
+ if (_num_palette>0){
+ SetPalette((rgb_color*)_palette,_num_palette);
+ SetClrImportant(_num_palette);
+ } else if (_bit_depth ==2) { //<DP> needed for 2 bpp grayscale PNGs
+ SetPaletteColor(0,0,0,0);
+ SetPaletteColor(1,85,85,85);
+ SetPaletteColor(2,170,170,170);
+ SetPaletteColor(3,255,255,255);
+ } else SetGrayPalette(); //<DP> needed for grayscale PNGs
+
+ int nshift = max(0,(_bit_depth>>3)-1)<<3;
+
+ png_bytep _trans_alpha;
+ int _num_trans;
+ png_color_16p _trans_color;
+#if PNG_LIBPNG_VER > 10399
+ png_get_tRNS(png_ptr,info_ptr,&_trans_alpha,&_num_trans,&_trans_color);
+#else
+ _num_trans=info_ptr->num_trans;
+#endif
+ if (_num_trans!=0){ //palette transparency
+ if (_num_trans==1){
+ if (_color_type == PNG_COLOR_TYPE_PALETTE){
+ info.nBkgndIndex = _trans_color->index;
+ } else{
+ info.nBkgndIndex = _trans_color->gray>>nshift;
+ }
+ }
+ if (_num_trans>1){
+ RGBQUAD* pal=GetPalette();
+ if (pal){
+ uint32_t ip;
+ if(_trans_alpha != 0) {
+ for (ip=0;ip<min(head.biClrUsed,(unsigned long)_num_trans);ip++)
+ pal[ip].rgbReserved=_trans_alpha[ip];
+ }
+ for (ip=_num_trans;ip<head.biClrUsed;ip++){
+ pal[ip].rgbReserved=255;
+ }
+ info.bAlphaPaletteEnabled=true;
+ }
+ }
+ }
+
+ if (channels == 3){ //check RGB binary transparency
+ /* seems unnecessary to call again, but the conditional must be important so... */
+ if (png_get_tRNS(png_ptr,info_ptr,&_trans_alpha,&_num_trans,&_trans_color)){
+ info.nBkgndColor.rgbRed = (uint8_t)(_trans_color->red>>nshift);
+ info.nBkgndColor.rgbGreen = (uint8_t)(_trans_color->green>>nshift);
+ info.nBkgndColor.rgbBlue = (uint8_t)(_trans_color->blue>>nshift);
+ info.nBkgndColor.rgbReserved = 0;
+ info.nBkgndIndex = 0;
+ }
+ }
+
+ int32_t alpha_present = (channels - 1) % 2;
+ if (alpha_present){
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ AlphaCreate();
+#else
+ png_set_strip_alpha(png_ptr);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+
+ // <vho> - flip the RGB pixels to BGR (or RGBA to BGRA)
+ if (_color_type & PNG_COLOR_MASK_COLOR){
+ png_set_bgr(png_ptr);
+ }
+
+ // <vho> - handle cancel
+ if (info.nEscape)
+#if PNG_LIBPNG_VER > 10399
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+
+ // row_bytes is the width x number of channels x (bit-depth / 8)
+#if PNG_LIBPNG_VER > 10399
+ row_pointers = new uint8_t[png_get_rowbytes(png_ptr,info_ptr) + 8];
+#else
+ row_pointers = new uint8_t[info_ptr->rowbytes + 8];
+#endif
+
+
+ // turn on interlace handling
+ int32_t number_passes = png_set_interlace_handling(png_ptr);
+
+ if (number_passes>1){
+ SetCodecOption( (ENCODE_INTERLACE) | GetCodecOption(CXIMAGE_FORMAT_PNG));
+ } else {
+ SetCodecOption(~(ENCODE_INTERLACE) & GetCodecOption(CXIMAGE_FORMAT_PNG));
+ }
+
+ int chan_offset = _bit_depth >> 3;
+#if PNG_LIBPNG_VER > 10399
+ int pixel_offset = (_bit_depth * png_get_channels(png_ptr,info_ptr)) >> 3;
+#else
+ int pixel_offset = info_ptr->pixel_depth >> 3;
+#endif
+
+ for (int32_t pass=0; pass < number_passes; pass++) {
+ iter.Upset();
+ int32_t y=0;
+ do {
+
+ // <vho> - handle cancel
+ if (info.nEscape)
+#if PNG_LIBPNG_VER > 10399
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ if (AlphaIsValid()) {
+
+ //compute the correct position of the line
+ int32_t ax,ay;
+ ay = head.biHeight-1-y;
+ uint8_t* prow= iter.GetRow(ay);
+
+ //recover data from previous scan
+ if (_interlace_type && pass>0 && pass!=7){
+ for(ax=0;ax<head.biWidth;ax++){
+ int32_t px = ax * pixel_offset;
+ if (channels == 2){
+ row_pointers[px] = prow[ax];
+ row_pointers[px+chan_offset]=AlphaGet(ax,ay);
+ } else {
+ int32_t qx = ax * 3;
+ row_pointers[px] =prow[qx];
+ row_pointers[px+chan_offset] =prow[qx+1];
+ row_pointers[px+chan_offset*2]=prow[qx+2];
+ row_pointers[px+chan_offset*3]=AlphaGet(ax,ay);
+ }
+ }
+ }
+
+ //read next row
+ png_read_row(png_ptr, row_pointers, NULL);
+
+ //RGBA -> RGB + A
+ for(ax=0;ax<head.biWidth;ax++){
+ int32_t px = ax * pixel_offset;
+ if (channels == 2){
+ prow[ax] = row_pointers[px];
+ AlphaSet(ax,ay,row_pointers[px+chan_offset]);
+ } else {
+ int32_t qx = ax * 3;
+ prow[qx] =row_pointers[px];
+ prow[qx+1]=row_pointers[px+chan_offset];
+ prow[qx+2]=row_pointers[px+chan_offset*2];
+ AlphaSet(ax,ay,row_pointers[px+chan_offset*3]);
+ }
+ }
+ } else
+#endif // CXIMAGE_SUPPORT_ALPHA // vho
+ {
+ //recover data from previous scan
+ if (_interlace_type && pass>0){
+#if PNG_LIBPNG_VER > 10399
+ iter.GetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr));
+#else
+ iter.GetRow(row_pointers, info_ptr->rowbytes);
+#endif
+ //re-expand buffer for images with bit depth > 8
+ if (_bit_depth > 8){
+ for(int32_t ax=(head.biWidth*channels-1);ax>=0;ax--)
+ row_pointers[ax*chan_offset] = row_pointers[ax];
+ }
+ }
+
+ //read next row
+ png_read_row(png_ptr, row_pointers, NULL);
+
+ //shrink 16 bit depth images down to 8 bits
+ if (_bit_depth > 8){
+ for(int32_t ax=0;ax<(head.biWidth*channels);ax++)
+ row_pointers[ax] = row_pointers[ax*chan_offset];
+ }
+
+ //copy the pixels
+#if PNG_LIBPNG_VER > 10399
+ iter.SetRow(row_pointers, png_get_rowbytes(png_ptr,info_ptr));
+#else
+ iter.SetRow(row_pointers, info_ptr->rowbytes);
+#endif
+ //<DP> expand 2 bpp images only in the last pass
+ if (_bit_depth==2 && pass==(number_passes-1))
+ expand2to4bpp(iter.GetRow());
+
+ //go on
+ iter.PrevRow();
+ }
+
+ y++;
+ } while(y<head.biHeight);
+ }
+
+ delete [] row_pointers;
+ row_pointers = NULL;
+
+ /* read the rest of the file, getting any additional chunks in info_ptr - REQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ /* clean up after the read, and free any memory allocated - REQUIRED */
+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_PNG) return true;
+ return false;
+ }
+ /* that's it */
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImagePNG::Encode(CxFile *hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ CImageIterator iter(this);
+ uint8_t trans[256]; //for transparency (don't move)
+ png_struct *png_ptr;
+ png_info *info_ptr;
+
+ cx_try
+ {
+ /* Create and initialize the png_struct with the desired error handler
+ * functions. If you want to use the default stderr and longjump method,
+ * you can supply NULL for the last three parameters. We also check that
+ * the library version is compatible with the one used at compile time,
+ * in case we are using dynamically linked libraries. REQUIRED.
+ */
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,(void *)NULL,NULL,NULL);
+ if (png_ptr == NULL) cx_throw("Failed to create PNG structure");
+
+ /* Allocate/initialize the image information data. REQUIRED */
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL){
+ png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+ cx_throw("Failed to initialize PNG info structure");
+ }
+
+ /* Set error handling. REQUIRED if you aren't supplying your own
+ * error hadnling functions in the png_create_write_struct() call.
+ */
+ if (setjmp(png_ptr->jmpbuf)){
+ /* If we get here, we had a problem reading the file */
+ if (info_ptr->palette) free(info_ptr->palette);
+ png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
+ cx_throw("Error saving PNG file");
+ }
+
+ /* set up the output control */
+ //png_init_io(png_ptr, hFile);
+
+ // use custom I/O functions
+ png_set_write_fn(png_ptr,hFile,/*(png_rw_ptr)*/user_write_data,/*(png_flush_ptr)*/user_flush_data);
+
+ /* set the file information here */
+ info_ptr->width = GetWidth();
+ info_ptr->height = GetHeight();
+ info_ptr->pixel_depth = (uint8_t)GetBpp();
+ info_ptr->channels = (GetBpp()>8) ? (uint8_t)3: (uint8_t)1;
+ info_ptr->bit_depth = (uint8_t)(GetBpp()/info_ptr->channels);
+ info_ptr->compression_type = info_ptr->filter_type = 0;
+ info_ptr->valid = 0;
+
+ // set interlace type
+ DWORD codec_opt = GetCodecOption(CXIMAGE_FORMAT_PNG);
+ if (codec_opt & CxImagePNG::ENCODE_INTERLACE)
+ info_ptr->interlace_type = PNG_INTERLACE_ADAM7;
+ else
+ info_ptr->interlace_type = PNG_INTERLACE_NONE;
+
+ /* set compression level */
+ int32_t compress_level;
+ switch (codec_opt & CxImagePNG::ENCODE_COMPRESSION_MASK)
+ {
+ case ENCODE_NO_COMPRESSION:
+ compress_level = Z_NO_COMPRESSION;
+ break;
+ case ENCODE_BEST_SPEED:
+ compress_level = Z_BEST_SPEED;
+ break;
+ case ENCODE_BEST_COMPRESSION:
+ compress_level = Z_BEST_COMPRESSION;
+ break;
+ default:
+ compress_level = Z_DEFAULT_COMPRESSION;
+ break;
+ }
+ png_set_compression_level(png_ptr, compress_level);
+
+ bool bGrayScale = IsGrayScale();
+
+ if (GetNumColors()){
+ if (bGrayScale){
+ info_ptr->color_type = PNG_COLOR_TYPE_GRAY;
+ } else {
+ info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ } else {
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ info_ptr->channels++;
+ info_ptr->bit_depth = 8;
+ info_ptr->pixel_depth += 8;
+ }
+#endif
+
+ /* set background */
+ png_color_16 image_background={ 0, 255, 255, 255, 0 };
+ RGBQUAD tc = GetTransColor();
+ if (info.nBkgndIndex>=0) {
+ image_background.blue = tc.rgbBlue;
+ image_background.green = tc.rgbGreen;
+ image_background.red = tc.rgbRed;
+ }
+ png_set_bKGD(png_ptr, info_ptr, &image_background);
+
+ /* set metrics */
+ png_set_pHYs(png_ptr, info_ptr, head.biXPelsPerMeter, head.biYPelsPerMeter, PNG_RESOLUTION_METER);
+
+ png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth,
+ info_ptr->color_type, info_ptr->interlace_type,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ //<DP> simple transparency
+ if (info.nBkgndIndex >= 0){
+ info_ptr->num_trans = 1;
+ info_ptr->valid |= PNG_INFO_tRNS;
+ info_ptr->trans_alpha = trans;
+ info_ptr->trans_color.index = (uint8_t)info.nBkgndIndex;
+ info_ptr->trans_color.red = tc.rgbRed;
+ info_ptr->trans_color.green = tc.rgbGreen;
+ info_ptr->trans_color.blue = tc.rgbBlue;
+ info_ptr->trans_color.gray = info_ptr->trans_color.index;
+
+ // the transparency indexes start from 0 for non grayscale palette
+ if (!bGrayScale && head.biClrUsed && info.nBkgndIndex)
+ SwapIndex(0,(uint8_t)info.nBkgndIndex);
+ }
+
+ /* set the palette if there is one */
+ if (GetPalette()){
+ if (!bGrayScale){
+ info_ptr->valid |= PNG_INFO_PLTE;
+ }
+
+ int32_t nc = GetClrImportant();
+ if (nc==0) nc = GetNumColors();
+
+ if (info.bAlphaPaletteEnabled){
+ for(uint16_t ip=0; ip<nc;ip++)
+ trans[ip]=GetPaletteColor((uint8_t)ip).rgbReserved;
+ info_ptr->num_trans = (uint16_t)nc;
+ info_ptr->valid |= PNG_INFO_tRNS;
+ info_ptr->trans_alpha = trans;
+ }
+
+ // copy the palette colors
+ info_ptr->palette = new png_color[nc];
+ info_ptr->num_palette = (png_uint_16) nc;
+ for (int32_t i=0; i<nc; i++)
+ GetPaletteColor(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ //Merge the transparent color with the alpha channel
+ if (AlphaIsValid() && head.biBitCount==24 && info.nBkgndIndex>=0){
+ for(int32_t y=0; y < head.biHeight; y++){
+ for(int32_t x=0; x < head.biWidth ; x++){
+ RGBQUAD c=GetPixelColor(x,y,false);
+ if (*(int32_t*)&c==*(int32_t*)&tc)
+ AlphaSet(x,y,0);
+ } } }
+#endif // CXIMAGE_SUPPORT_ALPHA // <vho>
+
+ int32_t row_size = max(info.dwEffWidth, info_ptr->width*info_ptr->channels*(info_ptr->bit_depth/8));
+ info_ptr->rowbytes = row_size;
+ uint8_t *row_pointers = new uint8_t[row_size];
+
+ /* write the file information */
+ png_write_info(png_ptr, info_ptr);
+
+ //interlace handling
+ int32_t num_pass = png_set_interlace_handling(png_ptr);
+ for (int32_t pass = 0; pass < num_pass; pass++){
+ //write image
+ iter.Upset();
+ int32_t ay=head.biHeight-1;
+ RGBQUAD c;
+ do {
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ if (AlphaIsValid()){
+ for (int32_t ax=head.biWidth-1; ax>=0;ax--){
+ c = BlindGetPixelColor(ax,ay);
+ int32_t px = ax * info_ptr->channels;
+ if (!bGrayScale){
+ row_pointers[px++]=c.rgbRed;
+ row_pointers[px++]=c.rgbGreen;
+ }
+ row_pointers[px++]=c.rgbBlue;
+ row_pointers[px] = AlphaGet(ax,ay);
+ }
+ png_write_row(png_ptr, row_pointers);
+ ay--;
+ }
+ else
+#endif //CXIMAGE_SUPPORT_ALPHA // <vho>
+ {
+ iter.GetRow(row_pointers, row_size);
+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB) //HACK BY OP
+ RGBtoBGR(row_pointers, row_size);
+ png_write_row(png_ptr, row_pointers);
+ }
+ } while(iter.PrevRow());
+ }
+
+ delete [] row_pointers;
+ row_pointers = NULL;
+
+ //if necessary, restore the original palette
+ if (!bGrayScale && head.biClrUsed && info.nBkgndIndex>0)
+ SwapIndex((uint8_t)info.nBkgndIndex,0);
+
+ /* It is REQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ /* if you malloced the palette, free it here */
+ if (info_ptr->palette){
+ delete [] (info_ptr->palette);
+ info_ptr->palette = NULL;
+ }
+
+ /* clean up after the write, and free any memory allocated */
+ png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return FALSE;
+ }
+ /* that's it */
+ return TRUE;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_PNG
diff --git a/archive/hge/CxImage/ximapng.h b/archive/hge/CxImage/ximapng.h new file mode 100644 index 0000000..262ea02 --- /dev/null +++ b/archive/hge/CxImage/ximapng.h @@ -0,0 +1,95 @@ +/*
+ * File: ximapng.h
+ * Purpose: PNG Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImagePNG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
+ *
+ * original CImagePNG and CImageIterator implementation are:
+ * Copyright: (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
+ *
+ * libpng Copyright (c) 1998-2003 Glenn Randers-Pehrson
+ * ==========================================================
+ */
+#if !defined(__ximaPNG_h)
+#define __ximaPNG_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_PNG
+
+extern "C" {
+#ifdef _LINUX
+ #undef _DLL
+ #include <png.h>
+#else
+ #include "../png/png.h"
+#endif
+}
+
+class CxImagePNG: public CxImage
+{
+public:
+ CxImagePNG(): CxImage(CXIMAGE_FORMAT_PNG) {}
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PNG);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PNG);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+ enum CODEC_OPTION
+ {
+ ENCODE_INTERLACE = 0x01,
+ // Exclusive compression types : 3 bit wide field
+ ENCODE_COMPRESSION_MASK = 0x0E,
+ ENCODE_NO_COMPRESSION = 1 << 1,
+ ENCODE_BEST_SPEED = 2 << 1,
+ ENCODE_BEST_COMPRESSION = 3 << 1,
+ ENCODE_DEFAULT_COMPRESSION = 4 << 1
+ };
+
+protected:
+ void ima_png_error(png_struct *png_ptr, char *message);
+ void expand2to4bpp(uint8_t* prow);
+
+ static void PNGAPI user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+ {
+ CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
+ if (hFile == NULL || hFile->Read(data,1,length) != length) png_error(png_ptr, "Read Error");
+ }
+
+ static void PNGAPI user_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+ {
+ CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
+ if (hFile == NULL || hFile->Write(data,1,length) != length) png_error(png_ptr, "Write Error");
+ }
+
+ static void PNGAPI user_flush_data(png_structp png_ptr)
+ {
+ CxFile* hFile = (CxFile*)png_get_io_ptr(png_ptr);
+ if (hFile == NULL || !hFile->Flush()) png_error(png_ptr, "Flush Error");
+ }
+
+ static void PNGAPI user_error_fn(png_structp png_ptr,png_const_charp error_msg)
+ {
+#if PNG_LIBPNG_VER > 10399
+ strncpy((char*)png_get_error_ptr(png_ptr),error_msg,255);
+ longjmp(png_jmpbuf(png_ptr), 1);
+#else
+ strncpy((char*)png_ptr->error_ptr,error_msg,255);
+ longjmp(png_ptr->jmpbuf, 1);
+#endif
+ }
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximapsd.cpp b/archive/hge/CxImage/ximapsd.cpp new file mode 100644 index 0000000..2d8417b --- /dev/null +++ b/archive/hge/CxImage/ximapsd.cpp @@ -0,0 +1,1307 @@ +/*
+ * File: ximapsd.cpp
+ * Purpose: Platform Independent PSD Image Class Loader
+ * Dec/2010 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ *
+ * libpsd (c) 2004-2007 Graphest Software
+ *
+ * Based on MyPSD class by Iosif Hamlatzis
+ * Details: http://www.codeproject.com/KB/graphics/MyPSD.aspx
+ * Cleaned up a bit and ported to CxImage by Vitaly Ovchinnikov
+ * Send feedback to vitaly(dot)ovchinnikov(at)gmail.com
+ */
+
+#include "ximapsd.h"
+
+#if CXIMAGE_SUPPORT_PSD
+
+enum {
+ PSD_FILE_HEADER,
+ PSD_COLOR_MODE_DATA,
+ PSD_IMAGE_RESOURCE,
+ PSD_LAYER_AND_MASK_INFORMATION,
+ PSD_IMAGE_DATA,
+ PSD_DONE
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_USE_LIBPSD == 0
+// MyPSD.h /////////////////////////////////////////////////////////////////////
+
+#ifndef __MyPSD_H__
+#define __MyPSD_H__
+
+namespace MyPSD
+{
+
+ class CPSD
+ {
+ struct HEADER_INFO
+ {
+ //Table 2-12: HeaderInfo Color spaces
+ // Color-ID Name Description
+ //-------------------------------------------
+ // 0 Bitmap // Probably means black & white
+ // 1 Grayscale The first value in the color data is the gray value, from 0...10000.
+ // 2 Indexed
+ // 3 RGB The first three values in the color data are red, green, and blue.
+ // They are full unsigned 16–bit values as in Apple’s RGBColor data
+ // structure. Pure red=65535,0,0.
+ // 4 CMYK The four values in the color data are cyan, magenta, yellow, and
+ // black. They are full unsigned 16–bit values. 0=100% ink. Pure
+ // cyan=0,65535,65535,65535.
+ // 7 Multichannel // Have no idea
+ // 8 Duotone
+ // 9 Lab The first three values in the color data are lightness, a chrominance,
+ // and b chrominance.
+ // Lightness is a 16–bit value from 0...100. The chromanance components
+ // are each 16–bit values from –128...127. Gray values
+ // are represented by chrominance components of 0. Pure
+ // white=100,0,0.
+ short nChannels;
+ int nHeight;
+ int nWidth;
+ short nBitsPerPixel;
+ short nColourMode;
+ HEADER_INFO();
+ };
+
+ struct COLOUR_MODE_DATA
+ {
+ int nLength;
+ unsigned char* ColourData;
+ COLOUR_MODE_DATA();
+ };
+
+
+ struct IMAGE_RESOURCE
+ {
+ // Table 2–1: Image resource block
+ // Type Name Description
+ //-------------------------------------------
+ // OSType Type Photoshop always uses its signature, 8BIM
+ // int16 ID Unique identifier
+ // PString Name A pascal string, padded to make size even (a null name consists of two bytes of 0)
+ // Pascal style string where the first byte gives the length of the
+ // string and the content bytes follow.
+ // int32 Size Actual size of resource data. This does not include the
+ // Type, ID, Name, or Size fields.
+ // Variable Data Resource data, padded to make size even
+ int nLength;
+ char OSType[4];
+ short nID;
+ unsigned char* Name;
+ int nSize;
+ IMAGE_RESOURCE();
+ void Reset();
+ };
+
+ struct RESOLUTION_INFO
+ {
+ // Table A-6: ResolutionInfo structure
+ // Type Name Description
+ //-------------------------------------------
+ // Fixed hRes Horizontal resolution in pixels per inch.
+ // int hResUnit 1=display horizontal resolution in pixels per inch;
+ // 2=display horizontal resolution in pixels per cm.
+ // short widthUnit Display width as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
+ // Fixed vRes Vertical resolution in pixels per inch.
+ // int vResUnit 1=display vertical resolution in pixels per inch;
+ // 2=display vertical resolution in pixels per cm.
+ // short heightUnit Display height as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
+ short hRes;
+ int hResUnit;
+ short widthUnit;
+
+ short vRes;
+ int vResUnit;
+ short heightUnit;
+ RESOLUTION_INFO();
+ };
+
+ struct RESOLUTION_INFO_v2 // Obsolete - Photoshop 2.0
+ {
+ short nChannels;
+ short nRows;
+ short nColumns;
+ short nDepth;
+ short nMode;
+ RESOLUTION_INFO_v2();
+ };
+
+ struct DISPLAY_INFO
+ {
+ // This structure contains display information about each channel.
+ //Table A-7: DisplayInfo Color spaces
+ // Color-ID Name Description
+ //-------------------------------------------
+ // 0 RGB The first three values in the color data are red, green, and blue.
+ // They are full unsigned 16–bit values as in Apple’s RGBColor data
+ // structure. Pure red=65535,0,0.
+ // 1 HSB The first three values in the color data are hue, saturation, and
+ // brightness. They are full unsigned 16–bit values as in Apple’s
+ // HSVColor data structure. Pure red=0,65535, 65535.
+ // 2 CMYK The four values in the color data are cyan, magenta, yellow, and
+ // black. They are full unsigned 16–bit values. 0=100% ink. Pure
+ // cyan=0,65535,65535,65535.
+ // 7 Lab The first three values in the color data are lightness, a chrominance,
+ // and b chrominance.
+ // Lightness is a 16–bit value from 0...10000. The chromanance components
+ // are each 16–bit values from –12800...12700. Gray values
+ // are represented by chrominance components of 0. Pure
+ // white=10000,0,0.
+ // 8 grayscale The first value in the color data is the gray value, from 0...10000.
+ short ColourSpace;
+ short Colour[4];
+ short Opacity; // 0..100
+ bool kind; // selected = 0, protected = 1
+ unsigned char padding; // should be zero
+ DISPLAY_INFO();
+ };
+ struct THUMBNAIL
+ {
+ // Adobe Photoshop 5.0 and later stores thumbnail information for preview
+ // display in an image resource block. These resource blocks consist of an
+ // 28 byte header, followed by a JFIF thumbnail in RGB (red, green, blue)
+ // for both Macintosh and Windows. Adobe Photoshop 4.0 stored the
+ // thumbnail information in the same format except the data section is
+ // (blue, green, red). The Adobe Photoshop 4.0 format is at resource ID
+ // and the Adobe Photoshop 5.0 format is at resource ID 1036.
+ // Table 2–5: Thumnail resource header
+ // Type Name Description
+ //-------------------------------------------
+ // 4 bytes format = 1 (kJpegRGB). Also supports kRawRGB (0).
+ // 4 bytes width Width of thumbnail in pixels.
+ // 4 bytes height Height of thumbnail in pixels.
+ // 4 bytes widthbytes Padded row bytes as (width * bitspixel + 31) / 32 * 4.
+ // 4 bytes size Total size as widthbytes * height * planes
+ // 4 bytes compressedsize Size after compression. Used for consistentcy check.
+ // 2 bytes bitspixel = 24. Bits per pixel.
+ // 2 bytes planes = 1. Number of planes.
+ // Variable Data JFIF data in RGB format.
+ // Note: For resource ID 1033 the data is in BGR format.
+ int nFormat;
+ int nWidth;
+ int nHeight;
+ int nWidthBytes;
+ int nSize;
+ int nCompressedSize;
+ short nBitPerPixel;
+ short nPlanes;
+ unsigned char* Data;
+ THUMBNAIL();
+ };
+
+
+ CxImage &m_image;
+
+ HEADER_INFO header_info;
+
+ COLOUR_MODE_DATA colour_mode_data;
+ short mnColourCount;
+ short mnTransparentIndex;
+
+ IMAGE_RESOURCE image_resource;
+
+ int mnGlobalAngle;
+
+ RESOLUTION_INFO resolution_info;
+ bool mbResolutionInfoFilled;
+
+ RESOLUTION_INFO_v2 resolution_info_v2;
+ bool mbResolutionInfoFilled_v2;
+
+ DISPLAY_INFO display_info;
+ bool mbDisplayInfoFilled;
+
+ THUMBNAIL thumbnail;
+ bool mbThumbNailFilled;
+
+ bool mbCopyright;
+
+ int Calculate(unsigned char* c, int nDigits);
+ void XYZToRGB(const double X, const double Y, const double Z, int &R, int &G, int &B);
+ void LabToRGB(const int L, const int a, const int b, int &R, int &G, int &B );
+ void CMYKToRGB(const double C, const double M, const double Y, const double K, int &R, int &G, int &B);
+
+ bool ReadHeader(CxFile &f, HEADER_INFO& header_info);
+ bool ReadColourModeData(CxFile &f, COLOUR_MODE_DATA& colour_mode_data);
+ bool ReadImageResource(CxFile &f, IMAGE_RESOURCE& image_resource);
+ bool ReadLayerAndMaskInfoSection(CxFile &f); // Actually ignore it
+ int ReadImageData(CxFile &f);
+
+ int DecodeRawData(CxFile &pFile);
+ int DecodeRLEData(CxFile &pFile);
+
+ void ProccessBuffer(unsigned char* pData = 0);
+
+ public:
+ CPSD(CxImage &image);
+ ~CPSD();
+
+ int Load(LPCTSTR szPathName);
+ int Load(CxFile &file);
+
+ bool ThumbNailIncluded() const { return mbThumbNailFilled; }
+ void DPI(int &x, int &y) const { x = resolution_info.hRes; y = resolution_info.vRes; }
+ void Dimensions(int &cx, int &cy) const { cx = header_info.nWidth; cy = header_info.nHeight; }
+ int BitsPerPixel() const { return header_info.nBitsPerPixel; }
+ int GlobalAngle() const { return mnGlobalAngle; }
+ bool IsCopyright() const { return mbCopyright; }
+ HBITMAP Detach();
+ };
+}
+
+#endif // __MyPSD_H__
+
+// MyPSD.cpp ///////////////////////////////////////////////////////////////////
+
+
+inline int dti(double value) { return (int)floor(value+.5f); }
+
+#define assert(a)
+
+#define mypsd_fread(a, b, c, d) d.Read(a, b, c)
+#define mypsd_fseek(a, b, c) a.Seek(b, c)
+#define mypsd_feof(a) a.Eof()
+
+namespace MyPSD
+{
+ CPSD::CPSD(CxImage &image) : m_image(image)
+ {
+ mbThumbNailFilled = false;
+ mbDisplayInfoFilled = false;
+ mbResolutionInfoFilled = false;
+ mbResolutionInfoFilled_v2 = false;
+ mnGlobalAngle = 30;
+ mbCopyright = false;
+ mnColourCount = -1;
+ mnTransparentIndex = -1;
+ }
+ CPSD::~CPSD()
+ {
+ // free memory
+ if ( 0 < colour_mode_data.nLength )
+ delete[] colour_mode_data.ColourData;
+ colour_mode_data.ColourData = 0;
+
+ if ( image_resource.Name )
+ delete[] image_resource.Name;
+ image_resource.Name = 0;
+ }
+
+ int CPSD::Calculate(unsigned char* c, int nDigits)
+ {
+ int nValue = 0;
+
+ for(int n = 0; n < nDigits; ++n)
+ nValue = ( nValue << 8 ) | *(c+n);
+
+ return nValue;
+ };
+
+ void CPSD::XYZToRGB(const double X, const double Y, const double Z, int &R, int &G, int &B)
+ {
+ // Standards used Observer = 2, Illuminant = D65
+ // ref_X = 95.047, ref_Y = 100.000, ref_Z = 108.883
+ const double ref_X = 95.047;
+ const double ref_Y = 100.000;
+ const double ref_Z = 108.883;
+
+ double var_X = X / 100.0;
+ double var_Y = Y / 100.0;
+ double var_Z = Z / 100.0;
+
+ double var_R = var_X * 3.2406 + var_Y * (-1.5372) + var_Z * (-0.4986);
+ double var_G = var_X * (-0.9689) + var_Y * 1.8758 + var_Z * 0.0415;
+ double var_B = var_X * 0.0557 + var_Y * (-0.2040) + var_Z * 1.0570;
+
+ if ( var_R > 0.0031308 )
+ var_R = 1.055 * ( pow(var_R, 1/2.4) ) - 0.055;
+ else
+ var_R = 12.92 * var_R;
+
+ if ( var_G > 0.0031308 )
+ var_G = 1.055 * ( pow(var_G, 1/2.4) ) - 0.055;
+ else
+ var_G = 12.92 * var_G;
+
+ if ( var_B > 0.0031308 )
+ var_B = 1.055 * ( pow(var_B, 1/2.4) )- 0.055;
+ else
+ var_B = 12.92 * var_B;
+
+ R = (int)(var_R * 256.0);
+ G = (int)(var_G * 256.0);
+ B = (int)(var_B * 256.0);
+ };
+
+ void CPSD::LabToRGB(const int L, const int a, const int b, int &R, int &G, int &B )
+ {
+ // For the conversion we first convert values to XYZ and then to RGB
+ // Standards used Observer = 2, Illuminant = D65
+ // ref_X = 95.047, ref_Y = 100.000, ref_Z = 108.883
+ const double ref_X = 95.047;
+ const double ref_Y = 100.000;
+ const double ref_Z = 108.883;
+
+ double var_Y = ( (double)L + 16.0 ) / 116.0;
+ double var_X = (double)a / 500.0 + var_Y;
+ double var_Z = var_Y - (double)b / 200.0;
+
+ if ( pow(var_Y, 3) > 0.008856 )
+ var_Y = pow(var_Y, 3);
+ else
+ var_Y = ( var_Y - 16 / 116 ) / 7.787;
+
+ if ( pow(var_X, 3) > 0.008856 )
+ var_X = pow(var_X, 3);
+ else
+ var_X = ( var_X - 16 / 116 ) / 7.787;
+
+ if ( pow(var_Z, 3) > 0.008856 )
+ var_Z = pow(var_Z, 3);
+ else
+ var_Z = ( var_Z - 16 / 116 ) / 7.787;
+
+ double X = ref_X * var_X;
+ double Y = ref_Y * var_Y;
+ double Z = ref_Z * var_Z;
+
+ XYZToRGB(X, Y, Z, R, G, B);
+ };
+
+ void CPSD::CMYKToRGB(const double C, const double M, const double Y, const double K, int &R, int &G, int &B )
+ {
+ R = dti( ( 1.0f - ( C *( 1.0f - K ) + K ) ) * 255.0f );
+ G = dti( ( 1.0f - ( M *( 1.0f - K ) + K ) ) * 255.0f );
+ B = dti( ( 1.0f - ( Y *( 1.0f - K ) + K ) ) * 255.0f );
+ };
+
+ bool CPSD::ReadLayerAndMaskInfoSection(CxFile &pFile) // Actually ignore it
+ {
+ bool bSuccess = false;
+
+ unsigned char DataLength[4];
+ int nBytesRead = 0;
+ int nItemsRead = (int)(int)mypsd_fread(&DataLength, sizeof(DataLength), 1, pFile);
+
+ int nTotalBytes = Calculate( DataLength, sizeof(DataLength) );
+
+ unsigned char data[1];
+ while( !mypsd_feof( pFile ) && ( nBytesRead < nTotalBytes ) )
+ {
+ data[0] = '\0';
+ nItemsRead = (int)(int)mypsd_fread(&data, sizeof(data), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(data);
+ }
+
+ assert ( nBytesRead == nTotalBytes );
+ if ( nBytesRead == nTotalBytes )
+ bSuccess = true;
+
+ return bSuccess;
+ }
+ bool CPSD::ReadImageResource(CxFile &pFile, IMAGE_RESOURCE& image_resource)
+ {
+ bool bSuccess = false;
+
+ unsigned char Length[4];
+ int nItemsRead = (int)(int)mypsd_fread(&Length, sizeof(Length), 1, pFile);
+
+ image_resource.nLength = Calculate( Length, sizeof(image_resource.nLength) );
+
+ int nBytesRead = 0;
+ int nTotalBytes = image_resource.nLength;
+
+ while( !mypsd_feof( pFile ) && ( nBytesRead < nTotalBytes ) )
+ {
+ nItemsRead = 0;
+ image_resource.Reset();
+
+ nItemsRead = (int)(int)mypsd_fread(&image_resource.OSType, sizeof(image_resource.OSType), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(image_resource.OSType);
+
+ assert ( 0 == (nBytesRead % 2) );
+ if (::memcmp(image_resource.OSType, "8BIM", 4) == 0)
+ {
+ unsigned char ID[2];
+ nItemsRead = (int)(int)mypsd_fread(&ID, sizeof(ID), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ID);
+
+ image_resource.nID = (short)Calculate( ID, sizeof(ID) );
+
+ unsigned char SizeOfName;
+ nItemsRead = (int)(int)mypsd_fread(&SizeOfName, sizeof(SizeOfName), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(SizeOfName);
+
+ int nSizeOfName = Calculate( &SizeOfName, sizeof(SizeOfName) );
+ if ( 0 < nSizeOfName )
+ {
+ image_resource.Name = new unsigned char[nSizeOfName];
+ nItemsRead = (int)(int)mypsd_fread(image_resource.Name, nSizeOfName, 1, pFile);
+ nBytesRead += nItemsRead * nSizeOfName;
+ }
+
+ if ( 0 == (nSizeOfName % 2) )
+ {
+ nItemsRead = (int)(int)mypsd_fread(&SizeOfName, sizeof(SizeOfName), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(SizeOfName);
+ }
+
+ unsigned char Size[4];
+ nItemsRead = (int)(int)mypsd_fread(&Size, sizeof(Size), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(Size);
+
+ image_resource.nSize = Calculate( Size, sizeof(image_resource.nSize) );
+
+ if ( 0 != (image_resource.nSize % 2) ) // resource data must be even
+ image_resource.nSize++;
+ if ( 0 < image_resource.nSize )
+ {
+ unsigned char IntValue[4];
+ unsigned char ShortValue[2];
+
+ switch( image_resource.nID )
+ {
+ case 1000:
+ {
+ // Obsolete - Photoshop 2.0
+ mbResolutionInfoFilled_v2 = true;
+
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info_v2.nChannels = (short)Calculate(ShortValue, sizeof(resolution_info_v2.nChannels) );
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info_v2.nRows = (short)Calculate(ShortValue, sizeof(resolution_info_v2.nRows) );
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info_v2.nColumns = (short)Calculate(ShortValue, sizeof(resolution_info_v2.nColumns) );
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info_v2.nDepth = (short)Calculate(ShortValue, sizeof(resolution_info_v2.nDepth) );
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info_v2.nMode = (short)Calculate(ShortValue, sizeof(resolution_info_v2.nMode) );
+ }
+ break;
+ case 1005:
+ {
+ mbResolutionInfoFilled = true;
+
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info.hRes = (short)Calculate(ShortValue, sizeof(resolution_info.hRes) );
+ nItemsRead = (int)(int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ resolution_info.hResUnit = Calculate(IntValue, sizeof(resolution_info.hResUnit) );
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info.widthUnit = (short)Calculate(ShortValue, sizeof(resolution_info.widthUnit) );
+
+ nItemsRead = (int)(int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info.vRes = (short)Calculate(ShortValue, sizeof(resolution_info.vRes) );
+ nItemsRead = (int)(int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ resolution_info.vResUnit = Calculate(IntValue, sizeof(resolution_info.vResUnit) );
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ resolution_info.heightUnit = (short)Calculate(ShortValue, sizeof(resolution_info.heightUnit) );
+ }
+ break;
+ case 1007:
+ {
+ mbDisplayInfoFilled = true;
+
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ display_info.ColourSpace = (short)Calculate(ShortValue, sizeof(display_info.ColourSpace) );
+
+ for ( unsigned int n = 0; n < 4; ++n )
+ {
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ display_info.Colour[n] = (short)Calculate(ShortValue, sizeof(display_info.Colour[n]) );
+ }
+
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ display_info.Opacity = (short)Calculate(ShortValue, sizeof(display_info.Opacity) );
+ assert ( 0 <= display_info.Opacity );
+ assert ( 100 >= display_info.Opacity );
+
+ unsigned char c[1];
+ nItemsRead = (int)mypsd_fread(&c, sizeof(c), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(c);
+ ( 1 == Calculate(c, sizeof(c) ) ) ? display_info.kind = true : display_info.kind = false;
+
+ nItemsRead = (int)mypsd_fread(&c, sizeof(c), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(c);
+ display_info.padding = (unsigned int)Calculate(c, sizeof(c) );
+ assert ( 0 == display_info.padding );
+ }
+ break;
+ case 1034:
+ {
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ ( 1 == Calculate(ShortValue, sizeof(ShortValue) ) ) ? mbCopyright = true : mbCopyright = false;
+ }
+ break;
+ case 1033:
+ case 1036:
+ {
+ mbThumbNailFilled = true;
+
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ thumbnail.nFormat = Calculate(IntValue, sizeof(thumbnail.nFormat) );
+
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ thumbnail.nWidth = Calculate(IntValue, sizeof(thumbnail.nWidth) );
+
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ thumbnail.nHeight = Calculate(IntValue, sizeof(thumbnail.nHeight) );
+
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ thumbnail.nWidthBytes = Calculate(IntValue, sizeof(thumbnail.nWidthBytes) );
+
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ thumbnail.nSize = Calculate(IntValue, sizeof(thumbnail.nSize) );
+
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ thumbnail.nCompressedSize = Calculate(IntValue, sizeof(thumbnail.nCompressedSize) );
+
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ thumbnail.nBitPerPixel = (short)Calculate(ShortValue, sizeof(thumbnail.nBitPerPixel) );
+
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ thumbnail.nPlanes = (short)Calculate(ShortValue, sizeof(thumbnail.nPlanes) );
+
+ int nTotalData = image_resource.nSize - 28; // header
+ unsigned char* buffer = new unsigned char[nTotalData];
+ unsigned char c[1];
+ if ( 1033 == image_resource.nID )
+ {
+ // In BGR format
+ for (int n = 0; n < nTotalData; n = n +3 )
+ {
+ nItemsRead = (int)mypsd_fread(&c, sizeof(unsigned char), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(unsigned char);
+ buffer[n+2] = (unsigned char)Calculate(c, sizeof(unsigned char) );
+ nItemsRead = (int)mypsd_fread(&c, sizeof(unsigned char), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(unsigned char);
+ buffer[n+1] = (unsigned char)Calculate(c, sizeof(BYTE) );
+ nItemsRead = (int)mypsd_fread(&c, sizeof(unsigned char), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(unsigned char);
+ buffer[n] = (unsigned char)Calculate(c, sizeof(unsigned char) );
+ }
+ }
+ else if ( 1036 == image_resource.nID )
+ {
+ // In RGB format
+ for (int n = 0; n < nTotalData; ++n )
+ {
+ nItemsRead = (int)mypsd_fread(&c, sizeof(BYTE), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(BYTE);
+ buffer[n] = (BYTE)Calculate(c, sizeof(BYTE) );
+ }
+ }
+
+ delete[] buffer;
+ buffer = 0;
+ }
+ break;
+ case 1037:
+ {
+ nItemsRead = (int)mypsd_fread(&IntValue, sizeof(IntValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(IntValue);
+ mnGlobalAngle = Calculate(IntValue, sizeof(mnGlobalAngle) );
+ }
+ break;
+ case 1046:
+ {
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ mnColourCount = (short)Calculate(ShortValue, sizeof(ShortValue) );
+ }
+ break;
+ case 1047:
+ {
+ nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ nBytesRead += nItemsRead * sizeof(ShortValue);
+ mnTransparentIndex = (short)Calculate(ShortValue, sizeof(ShortValue) );
+ }
+ break;
+
+ default:
+ pFile.Seek(image_resource.nSize, SEEK_CUR);
+ nBytesRead += image_resource.nSize;
+ break;
+ }
+ }
+ }
+ }
+
+ assert ( nBytesRead == nTotalBytes );
+ if ( nBytesRead == nTotalBytes )
+ bSuccess = true;
+
+ return bSuccess;
+ }
+ bool CPSD::ReadColourModeData(CxFile &pFile, COLOUR_MODE_DATA& colour_mode_data)
+ {
+ // Only indexed colour and duotone have colour mode data,
+ // for all other modes this section is 4 bytes length, the length field is set to zero
+
+ // For indexed color images, the length will be equal to 768, and the color
+ // will contain the color table for the image, in non–interleaved order.
+
+ // For duotone images, the color data will contain the duotone specification,
+ // the format of which is not documented. Other applications that read
+ // Photoshop files can treat a duotone image as a grayscale image, and just
+ // preserve the contents of the duotone information when reading and writing
+ // the file.
+
+ // free memory
+ if ( 0 < colour_mode_data.nLength )
+ delete[] colour_mode_data.ColourData;
+ colour_mode_data.ColourData = 0;
+
+ unsigned char Length[4];
+ int nItemsRead = (int)mypsd_fread(&Length, sizeof(Length), 1, pFile);
+
+ colour_mode_data.nLength = Calculate( Length, sizeof(colour_mode_data.nLength) );
+ if ( 0 < colour_mode_data.nLength )
+ {
+ colour_mode_data.ColourData = new unsigned char[colour_mode_data.nLength];
+ nItemsRead = 0;
+ memset(colour_mode_data.ColourData, 254, colour_mode_data.nLength);
+
+ nItemsRead += (int)mypsd_fread( colour_mode_data.ColourData, colour_mode_data.nLength, 1, pFile);
+
+ }
+
+ return true;
+ }
+
+ bool CPSD::ReadHeader(CxFile &pFile, HEADER_INFO& header_info)
+ {
+ bool bSuccess = false;
+
+ struct HEADER
+ {
+ char Signature[4]; // always equal 8BPS, do not read file if not
+ unsigned char Version[2]; // always equal 1, do not read file if not
+ char Reserved[6]; // must be zero
+ unsigned char Channels[2]; // numer of channels including any alpha channels, supported range 1 to 24
+ unsigned char Rows[4]; // height in PIXELS, supported range 1 to 30000
+ unsigned char Columns[4]; // width in PIXELS, supported range 1 to 30000
+ unsigned char Depth[2]; // number of bpp
+ unsigned char Mode[2]; // colour mode of the file,
+ // Btmap=0, Grayscale=1, Indexed=2, RGB=3,
+ // CMYK=4, Multichannel=7, Duotone=8, Lab=9
+ };
+
+ HEADER header;
+ int nItemsRead = (int)mypsd_fread(&header, sizeof(HEADER), 1, pFile);
+ if ( nItemsRead )
+ {
+ if ( 0 == ::memcmp(header.Signature, "8BPS", 4))
+ {
+ int nVersion = Calculate( header.Version, sizeof(header.Version) );
+
+ if ( 1 == nVersion )
+ {
+ unsigned int n = 0;
+ bool bOK = true;
+ while ( (n < 6) && bOK )
+ {
+ if ( '\0' != header.Reserved[n] )
+ bOK = false;
+ n++;
+ }
+ bSuccess = bOK;
+
+ if ( bSuccess )
+ {
+ header_info.nChannels = (short)Calculate( header.Channels, sizeof(header.Channels) );
+ header_info.nHeight = Calculate( header.Rows, sizeof(header.Rows) );
+ header_info.nWidth = Calculate( header.Columns, sizeof(header.Columns) );
+ header_info.nBitsPerPixel = (short)Calculate( header.Depth, sizeof(header.Depth) );
+ header_info.nColourMode = (short)Calculate( header.Mode, sizeof(header.Mode) );
+ }
+ }
+ }
+ }
+
+ return bSuccess;
+ }
+
+
+ void CPSD::ProccessBuffer(unsigned char* pData )
+ {
+ if (!pData) return;
+
+ switch ( header_info.nColourMode )
+ {
+ case 1: // Grayscale
+ case 8: // Duotone
+ {
+ bool bAlpha = header_info.nChannels > 1;
+
+ int nPixels = header_info.nWidth * header_info.nHeight;
+ byte *pRGBA = new byte[nPixels * (bAlpha ? 4 : 3)];
+ byte *pSrc = pData, *pDst = pRGBA;
+ for (int i = 0; i < nPixels; i++, pSrc += header_info.nChannels, pDst += bAlpha ? 4 : 3)
+ {
+ pDst[0] = pDst[1] = pDst[2] = pSrc[0];
+ if (bAlpha) pDst[3] = pSrc[1];
+ }
+
+ m_image.CreateFromArray(pRGBA, header_info.nWidth, header_info.nHeight, bAlpha ? 32 : 24, header_info.nWidth * (bAlpha ? 4 : 3), true);
+
+ delete [] pRGBA;
+ }
+ break;
+ case 2: // Indexed
+ {
+ if (!colour_mode_data.ColourData) break;
+ if (colour_mode_data.nLength != 768) break;
+ if (mnColourCount == 0) break;
+
+ int nPixels = header_info.nWidth * header_info.nHeight;
+ byte *pRGB = new byte[nPixels * 3];
+ ::memset(pRGB, 0, nPixels * 3);
+ byte *pSrc = pData, *pDst = pRGB;
+ for (int i = 0; i < nPixels; i++, pSrc += header_info.nChannels, pDst += 3)
+ {
+ int nIndex = *pSrc;
+ pDst[2] = colour_mode_data.ColourData[nIndex + 0 * 256];
+ pDst[1] = colour_mode_data.ColourData[nIndex + 1 * 256];
+ pDst[0] = colour_mode_data.ColourData[nIndex + 2 * 256];
+ }
+
+ m_image.CreateFromArray(pRGB, header_info.nWidth, header_info.nHeight, 24, header_info.nWidth * 3, true);
+ delete [] pRGB;
+ }
+ break;
+ case 3: // RGB
+ {
+ m_image.CreateFromArray(pData, header_info.nWidth, header_info.nHeight, header_info.nChannels == 3 ? 24 : 32, header_info.nWidth * header_info.nChannels, true);
+ m_image.SwapRGB2BGR();
+ }
+ break;
+ case 4: // CMYK
+ {
+ bool bAlpha = header_info.nChannels > 4;
+
+ int nPixels = header_info.nWidth * header_info.nHeight;
+ byte *pRGBA = new byte[nPixels * (bAlpha ? 4 : 3)];
+ byte *pSrc = pData, *pDst = pRGBA;
+ double C, M, Y, K;
+ int nRed, nGreen, nBlue;
+ for (int i = 0; i < nPixels; i++, pSrc += header_info.nChannels, pDst += bAlpha ? 4 : 3)
+ {
+ C = (1.0 - (double)pSrc[0] / 256);
+ M = (1.0 - (double)pSrc[1] / 256);
+ Y = (1.0 - (double)pSrc[2] / 256);
+ K = (1.0 - (double)pSrc[3] / 256);
+
+ CMYKToRGB(C, M, Y, K, nRed, nGreen, nBlue);
+
+ if (0 > nRed) nRed = 0; else if (255 < nRed) nRed = 255;
+ if (0 > nGreen) nGreen = 0; else if (255 < nGreen) nGreen = 255;
+ if (0 > nBlue) nBlue = 0; else if (255 < nBlue) nBlue = 255;
+
+ pDst[0] = nBlue; pDst[1] = nGreen; pDst[2] = nRed;
+ if (bAlpha) pDst[3] = pSrc[4];
+ }
+
+ m_image.CreateFromArray(pRGBA, header_info.nWidth, header_info.nHeight, bAlpha ? 32 : 24, header_info.nWidth * (bAlpha ? 4 : 3), true);
+
+ delete [] pRGBA;
+ }
+ break;
+ case 7: // Multichannel
+ {
+ if (header_info.nChannels == 0 || header_info.nChannels > 4) break; // ???
+
+ int nPixels = header_info.nWidth * header_info.nHeight;
+ byte *pRGB = new byte[nPixels * 3];
+ byte *pSrc = pData, *pDst = pRGB;
+ double C, M, Y, K;
+ int nRed, nGreen, nBlue;
+ for (int i = 0; i < nPixels; i++, pSrc += header_info.nChannels, pDst += 3)
+ {
+ C = M = Y = K = 0;
+ C = (1.0 - (double)pSrc[0] / 256);
+ if (header_info.nChannels > 1) M = (1.0 - (double)pSrc[1] / 256);
+ if (header_info.nChannels > 2) Y = (1.0 - (double)pSrc[2] / 256);
+ if (header_info.nChannels > 3) K = (1.0 - (double)pSrc[3] / 256);
+
+ CMYKToRGB(C, M, Y, K, nRed, nGreen, nBlue);
+
+ if (0 > nRed) nRed = 0; else if (255 < nRed) nRed = 255;
+ if (0 > nGreen) nGreen = 0; else if (255 < nGreen) nGreen = 255;
+ if (0 > nBlue) nBlue = 0; else if (255 < nBlue) nBlue = 255;
+
+ pDst[0] = nBlue; pDst[1] = nGreen; pDst[2] = nRed;
+ }
+
+ m_image.CreateFromArray(pRGB, header_info.nWidth, header_info.nHeight, 24, header_info.nWidth * 3, true);
+
+ delete [] pRGB;
+ }
+ break;
+ case 9: // Lab
+ {
+ bool bAlpha = header_info.nChannels > 3;
+
+ int nPixels = header_info.nWidth * header_info.nHeight;
+ byte *pRGBA = new byte[nPixels * (bAlpha ? 4 : 3)];
+ byte *pSrc = pData, *pDst = pRGBA;
+
+ double L_coef = 256.f / 100.f, a_coef = 256.f / 256.f, b_coef = 256.f / 256.f;
+ int L, a, b;
+ int nRed, nGreen, nBlue;
+ for (int i = 0; i < nPixels; i++, pSrc += header_info.nChannels, pDst += bAlpha ? 4 : 3)
+ {
+ L = (int)((float)pSrc[0] / L_coef);
+ a = (int)((float)pSrc[1] / a_coef - 128.0);
+ b = (int)((float)pSrc[2] / b_coef - 128.0);
+
+ LabToRGB(L, a, b, nRed, nGreen, nBlue );
+
+ if (0 > nRed) nRed = 0; else if (255 < nRed) nRed = 255;
+ if (0 > nGreen) nGreen = 0; else if (255 < nGreen) nGreen = 255;
+ if (0 > nBlue) nBlue = 0; else if (255 < nBlue) nBlue = 255;
+
+ pDst[0] = nBlue; pDst[1] = nGreen; pDst[2] = nRed;
+ if (bAlpha) pDst[3] = pSrc[3];
+ }
+
+ m_image.CreateFromArray(pRGBA, header_info.nWidth, header_info.nHeight, bAlpha ? 32 : 24, header_info.nWidth * (bAlpha ? 4 : 3), true);
+
+ delete [] pRGBA;
+ }
+ break;
+ }
+ }
+
+ int CPSD::Load(LPCTSTR szPathName)
+ {
+ CxIOFile f;
+ if (!f.Open(szPathName, _T("rb"))) return -1;
+ return Load(f);
+ }
+
+ int CPSD::Load(CxFile &f)
+ {
+ if (!ReadHeader(f, header_info)) return -2; // Error in header
+ if (!ReadColourModeData(f, colour_mode_data)) return -3; // Error in ColourMode Data
+ if (!ReadImageResource(f, image_resource)) return -4; // Error in Image Resource
+ if (!ReadLayerAndMaskInfoSection(f)) return -5; // Error in Mask Info
+ if (ReadImageData(f) != 0) return -6; // Error in Image Data
+ return 0; // all right
+ }
+
+ int CPSD::DecodeRawData( CxFile &pFile)
+ {
+ if (header_info.nBitsPerPixel != 8 && header_info.nBitsPerPixel != 16) return -7; // can't read this
+
+ int nWidth = header_info.nWidth;
+ int nHeight = header_info.nHeight;
+ int bytesPerPixelPerChannel = header_info.nBitsPerPixel / 8;
+
+ int nPixels = nWidth * nHeight;
+ int nTotalBytes = 0;
+
+ byte* pData = NULL;
+
+ switch ( header_info.nColourMode )
+ {
+ case 1: // Grayscale
+ case 2: // Indexed
+ case 3: // RGB
+ case 4: // CMYK
+ case 8: // Duotone
+ case 9: // Lab
+ {
+ // read RRRRRRRGGGGGGGBBBBBBAAAAAA data
+ int nAllDataSize = nPixels * bytesPerPixelPerChannel * header_info.nChannels;
+ byte *pFileData = new byte[nAllDataSize];
+ ::memset(pFileData, 0, nAllDataSize);
+ if (pFile.Read(pFileData, nAllDataSize, 1) != 1)
+ {
+ delete [] pFileData;
+ return -1; // bad data
+ }
+
+ // and convert them to RGBARGBARGBA data (depends on number of channels)
+ nTotalBytes = nPixels * header_info.nChannels;
+ pData = new byte[nTotalBytes];
+ byte *pSource = pFileData;
+ for (int nChannel = 0; nChannel < header_info.nChannels; nChannel++)
+ {
+ byte *pDest = pData + nChannel;
+ for (int pos = 0; pos < nPixels; pos++, pDest += header_info.nChannels, pSource += bytesPerPixelPerChannel) *pDest = *pSource;
+ }
+ delete [] pFileData;
+ }
+ break;
+ default:
+ return -1; // unsupported format
+ }
+
+ ProccessBuffer(pData);
+ delete [] pData;
+
+ // dpi related things
+ int ppm_x = 3780; // 96 dpi
+ int ppm_y = 3780; // 96 dpi
+ if (mbResolutionInfoFilled)
+ {
+ int nHorResolution = (int)resolution_info.hRes;
+ int nVertResolution = (int)resolution_info.vRes;
+ ppm_x = (nHorResolution * 10000) / 254;
+ ppm_y = (nVertResolution * 10000) / 254;
+ }
+ m_image.SetXDPI(ppm_x);
+ m_image.SetYDPI(ppm_y);
+
+ return 0;
+ }
+
+
+ int CPSD::DecodeRLEData(CxFile & pFile)
+ {
+ if (header_info.nBitsPerPixel != 8) return -7; // can't read this
+
+ int nWidth = header_info.nWidth;
+ int nHeight = header_info.nHeight;
+ int nPixels = nWidth * nHeight;
+
+ // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data
+ // read them and compute size of RLE data
+ int nLengthDataSize = nHeight * header_info.nChannels * 2;
+ byte *pLengthData = new byte[nLengthDataSize];
+ if (pFile.Read(pLengthData, nLengthDataSize, 1) != 1)
+ {
+ delete [] pLengthData;
+ return -1; // error while reading
+ }
+ int nRLEDataSize = 0;
+ for (int i = 0; i < nHeight * header_info.nChannels * 2; i += 2)
+ nRLEDataSize += Calculate(pLengthData + i, 2);
+ delete [] pLengthData;
+
+ // now read RLE data to the buffer for fast access
+ byte *pRLEData = new byte[nRLEDataSize];
+ if (pFile.Read(pRLEData, nRLEDataSize, 1) != 1)
+ {
+ delete [] pRLEData;
+ return -1;
+ }
+
+ // allocate buffer for raw data (RRRRRRR...RRRGGGGG...GGGGGGBBBBB...BBBBBAAAAA....AAAAA) it has the same size as the final buffer
+ // and the perform RLE-decoding
+ int nTotalBytes = nPixels * header_info.nChannels;
+ byte* pRawData = new byte[nTotalBytes];
+ byte *pRLESource = pRLEData, *pRLEDest = pRawData;
+ for (int channel = 0; channel < header_info.nChannels; channel++)
+ {
+ int nCount = 0;
+ while (nCount < nPixels)
+ {
+ int len = *pRLESource++;
+ if ( 128 > len )
+ { // copy next (len + 1) bytes as is
+ len++;
+ nCount += len;
+ ::memcpy(pRLEDest, pRLESource, len);
+ pRLEDest += len; pRLESource += len;
+ }
+ else if ( 128 < len )
+ {
+ // Next -len+1 bytes in the dest are replicated from next source byte.
+ // (Interpret len as a negative 8-bit int.)
+ len ^= 0x0FF;
+ len += 2;
+ nCount += len;
+ ::memset(pRLEDest, *pRLESource++, len);
+ pRLEDest += len;
+ }
+ else if ( 128 == len ) { /* Do nothing */ }
+ }
+ }
+ delete [] pRLEData;
+
+ // transform raw data to the good one (RGBARGBARGBA...RGBA)
+ byte *pRawSource = pRawData;
+ byte *pData = new byte[nTotalBytes];
+ int nPixelCounter = 0;
+ for( int nColour = 0; nColour < header_info.nChannels; ++nColour )
+ {
+ nPixelCounter = nColour;
+ for (int nPos = 0; nPos < nPixels; nPos++, pRawSource++)
+ {
+ pData[nPixelCounter] = *pRawSource;
+ nPixelCounter += header_info.nChannels;
+ }
+ }
+ delete[] pRawData;
+
+ // create image
+ ProccessBuffer(pData);
+ delete [] pData;
+
+ // dpi related things
+ int ppm_x = 3780; // 96 dpi
+ int ppm_y = 3780; // 96 dpi
+ if (mbResolutionInfoFilled)
+ {
+ int nHorResolution = (int)resolution_info.hRes;
+ int nVertResolution = (int)resolution_info.vRes;
+ ppm_x = (nHorResolution * 10000) / 254;
+ ppm_y = (nVertResolution * 10000) / 254;
+ }
+ m_image.SetXDPI(ppm_x);
+ m_image.SetYDPI(ppm_y);
+
+ return 0;
+ }
+
+ int CPSD::ReadImageData(CxFile &pFile)
+ {
+ int nErrorCode = 0; // No Errors
+
+ if ( !mypsd_feof(pFile) )
+ {
+ unsigned char ShortValue[2];
+ int nBytesRead = 0;
+ int nItemsRead = (int)mypsd_fread(&ShortValue, sizeof(ShortValue), 1, pFile);
+ short nCompression = (short)Calculate( ShortValue, sizeof(ShortValue) );
+
+ switch ( nCompression )
+ {
+ case 0: // raw data
+ nErrorCode = DecodeRawData(pFile);
+ break;
+ case 1: // RLE compression
+ nErrorCode = DecodeRLEData(pFile);
+ break;
+ case 2: // ZIP without prediction
+ nErrorCode = -10; // ZIP without prediction, no specification
+ break;
+ case 3: // ZIP with prediction
+ nErrorCode = -11; // ZIP with prediction, no specification
+ break;
+ default:
+ nErrorCode = -12; // Unknown format
+ }
+ }
+ return nErrorCode;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////
+ CPSD::HEADER_INFO::HEADER_INFO()
+ {
+ nChannels = -1;
+ nHeight = -1;
+ nWidth = -1;
+ nBitsPerPixel = -1;
+ nColourMode = -1;
+ }
+
+ CPSD::COLOUR_MODE_DATA::COLOUR_MODE_DATA()
+ {
+ nLength = -1;
+ ColourData = 0;
+ }
+
+ CPSD::IMAGE_RESOURCE::IMAGE_RESOURCE()
+ {
+ Name = 0;
+ Reset();
+ }
+
+ void CPSD::IMAGE_RESOURCE::Reset()
+ {
+ nLength = -1;
+ memset( OSType, '\0', sizeof(OSType) );
+ nID = -1;
+ if ( Name )
+ delete[] Name;
+ Name = 0;
+ nSize = -1;
+ }
+
+ CPSD::RESOLUTION_INFO::RESOLUTION_INFO()
+ {
+ hRes = -1;
+ hResUnit = -1;
+ widthUnit = -1;
+ vRes = -1;
+ vResUnit = -1;
+ heightUnit = -1;
+ }
+
+ CPSD::RESOLUTION_INFO_v2::RESOLUTION_INFO_v2()
+ {
+ nChannels = -1;
+ nRows = -1;
+ nColumns = -1;
+ nDepth = -1;
+ nMode = -1;
+ }
+
+ CPSD::DISPLAY_INFO::DISPLAY_INFO()
+ {
+ ColourSpace = -1;
+ for ( unsigned int n = 0; n < 4; ++n)
+ Colour[n] = 0;
+ Opacity = -1;
+ kind = false;
+ padding = '0';
+ }
+
+ CPSD::THUMBNAIL::THUMBNAIL()
+ {
+ nFormat = -1;
+ nWidth = -1;
+ nHeight = -1;
+ nWidthBytes = -1;
+ nSize = -1;
+ nCompressedSize = -1;
+ nBitPerPixel = -1;
+ nPlanes = -1;
+ Data = 0;
+ }
+} // MyPSD
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_USE_LIBPSD
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImagePSD::Decode(CxFile *hFile)
+{
+ if (hFile==NULL)
+ return false;
+
+#if CXIMAGE_USE_LIBPSD
+ psd_context* context = NULL;
+#endif
+
+ cx_try
+ {
+#if CXIMAGE_USE_LIBPSD
+
+ psd_status status;
+
+ context = (psd_context *)malloc(sizeof(psd_context));
+ if(context == NULL){
+ cx_throw("CxImagePSD: psd_status_malloc_failed");
+ }
+ memset(context, 0, sizeof(psd_context));
+
+ // install file manager
+ CxFilePsd src(hFile,context);
+
+ context->state = PSD_FILE_HEADER;
+ context->stream.file_length = hFile->Size();
+ context->load_tag = psd_load_tag_all;
+ status = psd_main_loop(context);
+
+ if(status != psd_status_done){
+ cx_throw("CxImagePSD: psd_main_loop failed");
+ }
+
+ Create(context->width,context->height,24,CXIMAGE_FORMAT_PSD);
+
+ uint8_t* rgba = (uint8_t*)context->merged_image_data;
+ uint8_t* alpha = NULL;
+ if (context->alpha_channel_info)
+ alpha = (uint8_t*)context->alpha_channel_info->channel_data;
+ if (alpha)
+ AlphaCreate();
+
+ int32_t x,y;
+ RGBQUAD c;
+ c.rgbReserved = 0;
+ if (rgba){
+ for(y =context->height-1; y--;){
+ for (x=0; x<context->width; x++){
+ c.rgbBlue = *rgba++;
+ c.rgbGreen = *rgba++;
+ c.rgbRed = *rgba++;
+ rgba++;
+ SetPixelColor(x,y,c);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (alpha) AlphaSet(x,y,*alpha++);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ }
+
+ psd_image_free(context);
+ free(context);
+
+#else //CXIMAGE_USE_LIBPSD == 0
+
+ MyPSD::CPSD psd(*this);
+ int nErrorCode = psd.Load(*hFile);
+ if (nErrorCode != 0) cx_throw("error loading PSD file");
+
+#endif //CXIMAGE_USE_LIBPSD
+
+ } cx_catch {
+
+#if CXIMAGE_USE_LIBPSD
+ psd_image_free(context);
+ if (context) free(context);
+#endif //CXIMAGE_USE_LIBPSD
+
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_PSD) return true;
+ return false;
+ }
+ /* that's it */
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImagePSD::Encode(CxFile * hFile)
+{
+ if (hFile == NULL) return false;
+ strcpy(info.szLastError, "Save PSD not supported");
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_PSD
+
diff --git a/archive/hge/CxImage/ximapsd.h b/archive/hge/CxImage/ximapsd.h new file mode 100644 index 0000000..92be8f1 --- /dev/null +++ b/archive/hge/CxImage/ximapsd.h @@ -0,0 +1,110 @@ +/*
+ * File: ximapsd.h
+ * Purpose: PSD Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImagePSD (c) Dec/2010
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * libpsd (c) 2004-2007 Graphest Software
+ *
+ * ==========================================================
+ */
+#if !defined(__ximaPSD_h)
+#define __ximaPSD_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_PSD
+
+#define CXIMAGE_USE_LIBPSD 1
+
+#if CXIMAGE_USE_LIBPSD
+ extern "C" {
+ #include "../libpsd/libpsd.h"
+ }
+#endif
+
+class CxImagePSD: public CxImage
+{
+
+public:
+ CxImagePSD(): CxImage(CXIMAGE_FORMAT_PSD) {}
+
+// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_PSD);}
+// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_PSD);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+//#if CXIMAGE_SUPPORT_EXIF
+// bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type);
+//#endif //CXIMAGE_SUPPORT_EXIF
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+#if CXIMAGE_USE_LIBPSD
+protected:
+ class CxFilePsd
+ {
+ public:
+ CxFilePsd(CxFile* pFile,psd_context *context)
+ {
+ context->file = pFile;
+
+ psd_CxFile_ops.size_ = psd_file_size;
+ psd_CxFile_ops.seek_ = psd_file_seek;
+ psd_CxFile_ops.read_ = psd_file_read;
+// psd_CxFile_ops.write_ = psd_file_write;
+// psd_CxFile_ops.close_ = psd_file_close;
+// psd_CxFile_ops.gets_ = psd_file_gets;
+// psd_CxFile_ops.eof_ = psd_file_eof;
+// psd_CxFile_ops.tell_ = psd_file_tell;
+// psd_CxFile_ops.getc_ = psd_file_getc;
+// psd_CxFile_ops.scanf_ = psd_file_scanf;
+
+ context->ops_ = &psd_CxFile_ops;
+
+ }
+
+ static int32_t psd_file_size(psd_file_obj *obj)
+ { return ((CxFile*)obj)->Size(); }
+
+ static int32_t psd_file_seek(psd_file_obj *obj, int32_t offset, int32_t origin)
+ { return ((CxFile*)obj)->Seek(offset,origin); }
+
+ static int32_t psd_file_read(psd_file_obj *obj, void *buf, int32_t size, int32_t cnt)
+ { return ((CxFile*)obj)->Read(buf,size,cnt); }
+
+// static int32_t psd_file_write(psd_file_obj *obj, void *buf, int32_t size, int32_t cnt)
+// { return ((CxFile*)obj)->Write(buf,size,cnt); }
+
+// static int32_t psd_file_close(psd_file_obj *obj)
+// { return 1; /*((CxFile*)obj)->Close();*/ }
+
+// static char* psd_file_gets(psd_file_obj *obj, char *string, int32_t n)
+// { return ((CxFile*)obj)->GetS(string,n); }
+
+// static int32_t psd_file_eof(psd_file_obj *obj)
+// { return ((CxFile*)obj)->Eof(); }
+
+// static long psd_file_tell(psd_file_obj *obj)
+// { return ((CxFile*)obj)->Tell(); }
+
+// static int32_t psd_file_getc(psd_file_obj *obj)
+// { return ((CxFile*)obj)->GetC(); }
+
+// static int32_t psd_file_scanf(psd_file_obj *obj,const char *format, void* output)
+// { return ((CxFile*)obj)->Scanf(format, output); }
+
+ private:
+ psd_file_ops psd_CxFile_ops;
+ };
+#endif //CXIMAGE_USE_LIBPSD
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximaraw.cpp b/archive/hge/CxImage/ximaraw.cpp new file mode 100644 index 0000000..aedc50a --- /dev/null +++ b/archive/hge/CxImage/ximaraw.cpp @@ -0,0 +1,331 @@ +/*
+ * File: ximaraw.cpp
+ * Purpose: Platform Independent RAW Image Class Loader
+ * 16/Dec/2007 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ *
+ * CxImageRAW (c) May/2006 pdw63
+ *
+ * based on dcraw.c -- Dave Coffin's raw photo decoder
+ * Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
+ */
+
+#include "ximaraw.h"
+
+#if CXIMAGE_SUPPORT_RAW
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageRAW::Decode(CxFile *hFile)
+{
+ if (hFile==NULL)
+ return false;
+
+ DCRAW dcr;
+
+ cx_try
+ {
+ // initialization
+ dcr_init_dcraw(&dcr);
+
+ dcr.opt.user_qual = GetCodecOption(CXIMAGE_FORMAT_RAW) & 0x03;
+
+ // setup variables for debugging
+ char szClass[] = "CxImageRAW";
+ dcr.ifname = szClass;
+ dcr.sz_error = info.szLastError;
+
+ // setup library options, see dcr_print_manual for the available switches
+ // call dcr_parse_command_line_options(&dcr,0,0,0) to set default options
+ // if (dcr_parse_command_line_options(&dcr,argc,argv,&arg))
+ if (dcr_parse_command_line_options(&dcr,0,0,0)){
+ cx_throw("CxImageRAW: unknown option");
+ }
+
+ // set return point for error handling
+ if (setjmp (dcr.failure)) {
+ cx_throw("");
+ }
+
+ // install file manager
+ CxFileRaw src(hFile,&dcr);
+
+ // check file header
+ dcr_identify(&dcr);
+
+ if(!dcr.is_raw){
+ cx_throw("CxImageRAW: not a raw image");
+ }
+
+ if (dcr.load_raw == NULL) {
+ cx_throw("CxImageRAW: missing raw decoder");
+ }
+
+ // verify special case
+ if (dcr.load_raw == dcr_kodak_ycbcr_load_raw) {
+ dcr.height += dcr.height & 1;
+ dcr.width += dcr.width & 1;
+ }
+
+ if (info.nEscape == -1){
+ head.biWidth = dcr.width;
+ head.biHeight= dcr.height;
+ info.dwType = CXIMAGE_FORMAT_RAW;
+ cx_throw("output dimensions returned");
+ }
+
+ // shrinked decoding available and requested?
+ dcr.shrink = dcr.filters && (dcr.opt.half_size || dcr.opt.threshold || dcr.opt.aber[0] != 1 || dcr.opt.aber[2] != 1);
+ dcr.iheight = (dcr.height + dcr.shrink) >> dcr.shrink;
+ dcr.iwidth = (dcr.width + dcr.shrink) >> dcr.shrink;
+
+ // install custom camera matrix
+ if (dcr.opt.use_camera_matrix && dcr.cmatrix[0][0] > 0.25) {
+ memcpy (dcr.rgb_cam, dcr.cmatrix, sizeof dcr.cmatrix);
+ dcr.raw_color = 0;
+ } else {
+ dcr.opt.use_camera_wb = 1;
+ }
+
+ // allocate memory for the image
+ dcr.image = (ushort (*)[4]) calloc (dcr.iheight*dcr.iwidth, sizeof *dcr.image);
+ dcr_merror (&dcr, dcr.image, szClass);
+
+ if (dcr.meta_length) {
+ dcr.meta_data = (char *) malloc (dcr.meta_length);
+ dcr_merror (&dcr, dcr.meta_data, szClass);
+ }
+
+ // start image decoder
+ hFile->Seek(dcr.data_offset, SEEK_SET);
+ (*dcr.load_raw)(&dcr);
+
+ // post processing
+ if (dcr.zero_is_bad) dcr_remove_zeroes(&dcr);
+
+ dcr_bad_pixels(&dcr,dcr.opt.bpfile);
+
+ if (dcr.opt.dark_frame) dcr_subtract (&dcr,dcr.opt.dark_frame);
+
+ dcr.quality = 2 + !dcr.fuji_width;
+
+ if (dcr.opt.user_qual >= 0) dcr.quality = dcr.opt.user_qual;
+
+ if (dcr.opt.user_black >= 0) dcr.black = dcr.opt.user_black;
+
+ if (dcr.opt.user_sat >= 0) dcr.maximum = dcr.opt.user_sat;
+
+#ifdef COLORCHECK
+ dcr_colorcheck(&dcr);
+#endif
+
+#if RESTRICTED
+ if (dcr.is_foveon && !dcr.opt.document_mode) dcr_foveon_interpolate(&dcr);
+#endif
+
+ if (!dcr.is_foveon && dcr.opt.document_mode < 2) dcr_scale_colors(&dcr);
+
+ // pixel interpolation and filters
+ dcr_pre_interpolate(&dcr);
+
+ if (dcr.filters && !dcr.opt.document_mode) {
+ if (dcr.quality == 0)
+ dcr_lin_interpolate(&dcr);
+ else if (dcr.quality == 1 || dcr.colors > 3)
+ dcr_vng_interpolate(&dcr);
+ else if (dcr.quality == 2)
+ dcr_ppg_interpolate(&dcr);
+ else
+ dcr_ahd_interpolate(&dcr);
+ }
+
+ if (dcr.mix_green) {
+ int32_t i;
+ for (dcr.colors=3, i=0; i < dcr.height*dcr.width; i++) {
+ dcr.image[i][1] = (dcr.image[i][1] + dcr.image[i][3]) >> 1;
+ }
+ }
+
+ if (!dcr.is_foveon && dcr.colors == 3) dcr_median_filter(&dcr);
+
+ if (!dcr.is_foveon && dcr.opt.highlight == 2) dcr_blend_highlights(&dcr);
+
+ if (!dcr.is_foveon && dcr.opt.highlight > 2) dcr_recover_highlights(&dcr);
+
+ if (dcr.opt.use_fuji_rotate) dcr_fuji_rotate(&dcr);
+
+#ifndef NO_LCMS
+ if (dcr.opt.cam_profile) dcr_apply_profile (dcr.opt.cam_profile, dcr.opt.out_profile);
+#endif
+
+ // final conversion
+ dcr_convert_to_rgb(&dcr);
+
+ if (dcr.opt.use_fuji_rotate) dcr_stretch(&dcr);
+
+ dcr.iheight = dcr.height;
+ dcr.iwidth = dcr.width;
+ if (dcr.flip & 4) SWAP(dcr.height,dcr.width);
+
+ // ready to transfer data from dcr.image
+ if (!Create(dcr.width,dcr.height,24,CXIMAGE_FORMAT_RAW)){
+ cx_throw("");
+ }
+
+ uchar *ppm = (uchar *) calloc (dcr.width, dcr.colors*dcr.opt.output_bps/8);
+ ushort *ppm2 = (ushort *) ppm;
+ dcr_merror (&dcr, ppm, szClass);
+
+ uchar lut[0x10000];
+ if (dcr.opt.output_bps == 8) dcr_gamma_lut (&dcr, lut);
+
+ int32_t c, row, col, soff, rstep, cstep;
+ soff = dcr_flip_index (&dcr, 0, 0);
+ cstep = dcr_flip_index (&dcr, 0, 1) - soff;
+ rstep = dcr_flip_index (&dcr, 1, 0) - dcr_flip_index (&dcr, 0, dcr.width);
+ for (row=0; row < dcr.height; row++, soff += rstep) {
+ for (col=0; col < dcr.width; col++, soff += cstep) {
+ if (dcr.opt.output_bps == 8)
+ for (c=0; c < dcr.colors; c++) ppm [col*dcr.colors+c] = lut[dcr.image[soff][c]];
+ else
+ for (c=0; c < dcr.colors; c++) ppm2[col*dcr.colors+c] = dcr.image[soff][c];
+ }
+ if (dcr.opt.output_bps == 16 && !dcr.opt.output_tiff && htons(0x55aa) != 0x55aa)
+#if defined(_LINUX) || defined(__APPLE__)
+ swab ((char*)ppm2, (char*)ppm2, dcr.width*dcr.colors*2);
+#else
+ _swab ((char*)ppm2, (char*)ppm2, dcr.width*dcr.colors*2);
+#endif
+
+ uint32_t size = dcr.width * (dcr.colors*dcr.opt.output_bps/8);
+ RGBtoBGR(ppm,size);
+ memcpy(GetBits(dcr.height - 1 - row), ppm, min(size,GetEffWidth()));
+ }
+ free (ppm);
+
+
+ dcr_cleanup_dcraw(&dcr);
+
+ } cx_catch {
+
+ dcr_cleanup_dcraw(&dcr);
+
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_RAW) return true;
+ return false;
+ }
+ /* that's it */
+ return true;
+}
+
+#if CXIMAGE_SUPPORT_EXIF
+bool CxImageRAW::GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type)
+{
+ DCRAW dcr;
+
+ CxIOFile file;
+ if (!file.Open(filename, _T("rb")))
+ return false;
+
+ cx_try
+ {
+ // initialization
+ dcr_init_dcraw(&dcr);
+
+ dcr.opt.user_qual = GetCodecOption(CXIMAGE_FORMAT_RAW) & 0x03;
+
+ // setup variables for debugging
+ char szClass[] = "CxImageRAW";
+ dcr.ifname = szClass;
+ dcr.sz_error = info.szLastError;
+
+ // setup library options, see dcr_print_manual for the available switches
+ // call dcr_parse_command_line_options(&dcr,0,0,0) to set default options
+ // if (dcr_parse_command_line_options(&dcr,argc,argv,&arg))
+ if (dcr_parse_command_line_options(&dcr,0,0,0)){
+ cx_throw("CxImageRAW: unknown option");
+ }
+
+ // set return point for error handling
+ if (setjmp (dcr.failure)) {
+ cx_throw("");
+ }
+
+ // install file manager
+ CxFileRaw src(&file,&dcr);
+
+ // check file header
+ dcr_identify(&dcr);
+
+ if(!dcr.is_raw){
+ cx_throw("CxImageRAW: not a raw image");
+ }
+
+ if (dcr.load_raw == NULL) {
+ cx_throw("CxImageRAW: missing raw decoder");
+ }
+
+ // THUMB.
+ if (dcr.thumb_offset != 0)
+ {
+ FILE* file = _tfopen(outname, _T("wb"));
+ DCRAW* p = &dcr;
+ dcr_fseek(dcr.obj_, dcr.thumb_offset, SEEK_SET);
+ dcr.write_thumb(&dcr, file);
+ fclose(file);
+
+ // Read in the thumbnail to resize and rotate.
+ CxImage image(outname, CXIMAGE_FORMAT_UNKNOWN);
+ if (image.IsValid())
+ {
+ // Resizing.
+ if (image.GetWidth() > 256 || image.GetHeight() > 256)
+ {
+ float amount = 256.0f / max(image.GetWidth(), image.GetHeight());
+ image.Resample((int32_t)(image.GetWidth() * amount), (int32_t)(image.GetHeight() * amount), 0);
+ }
+
+ // Rotation.
+ if (p->flip != 0)
+ image.RotateExif(p->flip);
+
+ return image.Save(outname, CXIMAGE_FORMAT_JPG);
+ }
+ }
+ else
+ {
+ cx_throw("No thumbnail!");
+ }
+
+ dcr_cleanup_dcraw(&dcr);
+
+ } cx_catch {
+
+ dcr_cleanup_dcraw(&dcr);
+
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_RAW) return true;
+ return false;
+ }
+ /* that's it */
+ return true;
+}
+#endif //CXIMAGE_SUPPORT_EXIF
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageRAW::Encode(CxFile * hFile)
+{
+ if (hFile == NULL) return false;
+ strcpy(info.szLastError, "Save RAW not supported");
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_RAW
+
diff --git a/archive/hge/CxImage/ximaraw.h b/archive/hge/CxImage/ximaraw.h new file mode 100644 index 0000000..2fe4961 --- /dev/null +++ b/archive/hge/CxImage/ximaraw.h @@ -0,0 +1,112 @@ +/*
+ * File: ximaraw.h
+ * Purpose: RAW Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageRAW (c) May/2006 pdw63
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ * Special thanks to David Coffin for dcraw without which this class would not exist
+ *
+ * libdcr (c) Dec/2007 Davide Pizzolato - www.xdp.it
+ *
+ * based on dcraw.c -- Dave Coffin's raw photo decoder
+ * Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
+ * ==========================================================
+ */
+#if !defined(__ximaRAW_h)
+#define __ximaRAW_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_RAW
+
+extern "C" {
+ #include "../raw/libdcr.h"
+}
+
+class CxImageRAW: public CxImage
+{
+
+public:
+ CxImageRAW(): CxImage(CXIMAGE_FORMAT_RAW) {}
+
+// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
+// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_EXIF
+ bool GetExifThumbnail(const TCHAR *filename, const TCHAR *outname, int32_t type);
+#endif //CXIMAGE_SUPPORT_EXIF
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+ enum CODEC_OPTION
+ {
+ DECODE_QUALITY_LIN = 0x00,
+ DECODE_QUALITY_VNG = 0x01,
+ DECODE_QUALITY_PPG = 0x02,
+ DECODE_QUALITY_AHD = 0x03,
+ };
+
+protected:
+
+ class CxFileRaw
+ {
+ public:
+ CxFileRaw(CxFile* pFile,DCRAW *stream)
+ {
+ stream->obj_ = pFile;
+
+ ras_stream_CxFile.read_ = raw_sfile_read;
+ ras_stream_CxFile.write_ = raw_sfile_write;
+ ras_stream_CxFile.seek_ = raw_sfile_seek;
+ ras_stream_CxFile.close_ = raw_sfile_close;
+ ras_stream_CxFile.gets_ = raw_sfile_gets;
+ ras_stream_CxFile.eof_ = raw_sfile_eof;
+ ras_stream_CxFile.tell_ = raw_sfile_tell;
+ ras_stream_CxFile.getc_ = raw_sfile_getc;
+ ras_stream_CxFile.scanf_ = raw_sfile_scanf;
+
+ stream->ops_ = &ras_stream_CxFile;
+
+ }
+
+ static int32_t raw_sfile_read(dcr_stream_obj *obj, void *buf, int32_t size, int32_t cnt)
+ { return ((CxFile*)obj)->Read(buf,size,cnt); }
+
+ static int32_t raw_sfile_write(dcr_stream_obj *obj, void *buf, int32_t size, int32_t cnt)
+ { return ((CxFile*)obj)->Write(buf,size,cnt); }
+
+ static long raw_sfile_seek(dcr_stream_obj *obj, long offset, int32_t origin)
+ { return ((CxFile*)obj)->Seek(offset,origin); }
+
+ static int32_t raw_sfile_close(dcr_stream_obj *obj)
+ { return 1; /*((CxFile*)obj)->Close();*/ }
+
+ static char* raw_sfile_gets(dcr_stream_obj *obj, char *string, int32_t n)
+ { return ((CxFile*)obj)->GetS(string,n); }
+
+ static int32_t raw_sfile_eof(dcr_stream_obj *obj)
+ { return ((CxFile*)obj)->Eof(); }
+
+ static long raw_sfile_tell(dcr_stream_obj *obj)
+ { return ((CxFile*)obj)->Tell(); }
+
+ static int32_t raw_sfile_getc(dcr_stream_obj *obj)
+ { return ((CxFile*)obj)->GetC(); }
+
+ static int32_t raw_sfile_scanf(dcr_stream_obj *obj,const char *format, void* output)
+ { return ((CxFile*)obj)->Scanf(format, output); }
+
+ private:
+ dcr_stream_ops ras_stream_CxFile;
+ };
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximasel.cpp b/archive/hge/CxImage/ximasel.cpp new file mode 100644 index 0000000..c50ff99 --- /dev/null +++ b/archive/hge/CxImage/ximasel.cpp @@ -0,0 +1,698 @@ +// xImaSel.cpp : Selection functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the image has a valid selection.
+ */
+bool CxImage::SelectionIsValid()
+{
+ return pSelection!=0;
+}
+
+#if CXIMAGE_SUPPORT_SELECTION
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Gets the smallest rectangle that contains the selection
+ */
+void CxImage::SelectionGetBox(RECT& r)
+{
+ memcpy(&r,&info.rSelectionBox,sizeof(RECT));
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Empties the selection.
+ */
+bool CxImage::SelectionClear(uint8_t level)
+{
+ if (pSelection){
+ if (level==0){
+ memset(pSelection,0,head.biWidth * head.biHeight);
+ info.rSelectionBox.left = head.biWidth;
+ info.rSelectionBox.bottom = head.biHeight;
+ info.rSelectionBox.right = info.rSelectionBox.top = 0;
+ } else {
+ memset(pSelection,level,head.biWidth * head.biHeight);
+ info.rSelectionBox.right = head.biWidth;
+ info.rSelectionBox.top = head.biHeight;
+ info.rSelectionBox.left = info.rSelectionBox.bottom = 0;
+ }
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Allocates an empty selection.
+ */
+bool CxImage::SelectionCreate()
+{
+ SelectionDelete();
+ pSelection = (uint8_t*)calloc(head.biWidth * head.biHeight, 1);
+ return (pSelection!=0);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Deallocates the selction.
+ */
+bool CxImage::SelectionDelete()
+{
+ if (pSelection){
+ free(pSelection);
+ pSelection=NULL;
+ }
+ info.rSelectionBox.left = head.biWidth;
+ info.rSelectionBox.bottom = head.biHeight;
+ info.rSelectionBox.right = info.rSelectionBox.top = 0;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the coordinates are inside the selection.
+ */
+bool CxImage::SelectionIsInside(int32_t x, int32_t y)
+{
+ if (IsInside(x,y)){
+ if (pSelection==NULL) return true;
+ return pSelection[x+y*head.biWidth]!=0;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Checks if the coordinates are inside the selection.
+ * "blind" version assumes that (x,y) is inside to the image.
+ */
+bool CxImage::BlindSelectionIsInside(int32_t x, int32_t y)
+{
+#ifdef _DEBUG
+ if (!IsInside(x,y))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return 0;
+ #endif
+#endif
+ if (pSelection==NULL) return true;
+ return pSelection[x+y*head.biWidth]!=0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds a rectangle to the existing selection.
+ */
+bool CxImage::SelectionAddRect(RECT r, uint8_t level)
+{
+ if (pSelection==NULL) SelectionCreate();
+ if (pSelection==NULL) return false;
+
+ RECT r2;
+ if (r.left<r.right) {r2.left=r.left; r2.right=r.right; } else {r2.left=r.right ; r2.right=r.left; }
+ if (r.bottom<r.top) {r2.bottom=r.bottom; r2.top=r.top; } else {r2.bottom=r.top ; r2.top=r.bottom; }
+
+ if (info.rSelectionBox.top <= r2.top) info.rSelectionBox.top = max(0L,min(head.biHeight,r2.top+1));
+ if (info.rSelectionBox.left > r2.left) info.rSelectionBox.left = max(0L,min(head.biWidth,r2.left));
+ if (info.rSelectionBox.right <= r2.right) info.rSelectionBox.right = max(0L,min(head.biWidth,r2.right+1));
+ if (info.rSelectionBox.bottom > r2.bottom) info.rSelectionBox.bottom = max(0L,min(head.biHeight,r2.bottom));
+
+ int32_t ymin = max(0L,min(head.biHeight,r2.bottom));
+ int32_t ymax = max(0L,min(head.biHeight,r2.top+1));
+ int32_t xmin = max(0L,min(head.biWidth,r2.left));
+ int32_t xmax = max(0L,min(head.biWidth,r2.right+1));
+
+ for (int32_t y=ymin; y<ymax; y++)
+ memset(pSelection + xmin + y * head.biWidth, level, xmax-xmin);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds an ellipse to the existing selection.
+ */
+bool CxImage::SelectionAddEllipse(RECT r, uint8_t level)
+{
+ if (pSelection==NULL) SelectionCreate();
+ if (pSelection==NULL) return false;
+
+ int32_t xradius = abs(r.right - r.left)/2;
+ int32_t yradius = abs(r.top - r.bottom)/2;
+ if (xradius==0 || yradius==0) return false;
+
+ int32_t xcenter = (r.right + r.left)/2;
+ int32_t ycenter = (r.top + r.bottom)/2;
+
+ if (info.rSelectionBox.left > (xcenter - xradius)) info.rSelectionBox.left = max(0L,min(head.biWidth,(xcenter - xradius)));
+ if (info.rSelectionBox.right <= (xcenter + xradius)) info.rSelectionBox.right = max(0L,min(head.biWidth,(xcenter + xradius + 1)));
+ if (info.rSelectionBox.bottom > (ycenter - yradius)) info.rSelectionBox.bottom = max(0L,min(head.biHeight,(ycenter - yradius)));
+ if (info.rSelectionBox.top <= (ycenter + yradius)) info.rSelectionBox.top = max(0L,min(head.biHeight,(ycenter + yradius + 1)));
+
+ int32_t xmin = max(0L,min(head.biWidth,xcenter - xradius));
+ int32_t xmax = max(0L,min(head.biWidth,xcenter + xradius + 1));
+ int32_t ymin = max(0L,min(head.biHeight,ycenter - yradius));
+ int32_t ymax = max(0L,min(head.biHeight,ycenter + yradius + 1));
+
+ int32_t y,yo;
+ for (y=ymin; y<min(ycenter,ymax); y++){
+ for (int32_t x=xmin; x<xmax; x++){
+ yo = (int32_t)(ycenter - yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
+ if (yo<y) pSelection[x + y * head.biWidth] = level;
+ }
+ }
+ for (y=ycenter; y<ymax; y++){
+ for (int32_t x=xmin; x<xmax; x++){
+ yo = (int32_t)(ycenter + yradius * sqrt(1-pow((float)(x - xcenter)/(float)xradius,2)));
+ if (yo>y) pSelection[x + y * head.biWidth] = level;
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Inverts the selection.
+ * Note: the SelectionBox is set to "full image", call SelectionGetBox before (if necessary)
+ */
+bool CxImage::SelectionInvert()
+{
+ if (pSelection) {
+ uint8_t *iSrc=pSelection;
+ int32_t n=head.biHeight*head.biWidth;
+ for(int32_t i=0; i < n; i++){
+ *iSrc=(uint8_t)~(*(iSrc));
+ iSrc++;
+ }
+
+ SelectionRebuildBox();
+
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Imports an existing region from another image with the same width and height.
+ */
+bool CxImage::SelectionCopy(CxImage &from)
+{
+ if (from.pSelection == NULL || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight) return false;
+ if (pSelection==NULL) pSelection = (uint8_t*)malloc(head.biWidth * head.biHeight);
+ if (pSelection==NULL) return false;
+ memcpy(pSelection,from.pSelection,head.biWidth * head.biHeight);
+ memcpy(&info.rSelectionBox,&from.info.rSelectionBox,sizeof(RECT));
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds a polygonal region to the existing selection. points points to an array of POINT structures.
+ * Each structure specifies the x-coordinate and y-coordinate of one vertex of the polygon.
+ * npoints specifies the number of POINT structures in the array pointed to by points.
+ */
+bool CxImage::SelectionAddPolygon(POINT *points, int32_t npoints, uint8_t level)
+{
+ if (points==NULL || npoints<3) return false;
+
+ if (pSelection==NULL) SelectionCreate();
+ if (pSelection==NULL) return false;
+
+ uint8_t* plocal = (uint8_t*)calloc(head.biWidth*head.biHeight, 1);
+ RECT localbox = {head.biWidth,0,0,head.biHeight};
+
+ int32_t x,y,i=0;
+ POINT *current;
+ POINT *next = NULL;
+ POINT *start = NULL;
+ //trace contour
+ while (i < npoints){
+ current = &points[i];
+ if (current->x!=-1){
+ if (i==0 || (i>0 && points[i-1].x==-1)) start = &points[i];
+
+ if ((i+1)==npoints || points[i+1].x==-1)
+ next = start;
+ else
+ next = &points[i+1];
+
+ float beta;
+ if (current->x != next->x){
+ beta = (float)(next->y - current->y)/(float)(next->x - current->x);
+ if (current->x < next->x){
+ for (x=current->x; x<=next->x; x++){
+ y = (int32_t)(current->y + (x - current->x) * beta);
+ if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
+ }
+ } else {
+ for (x=current->x; x>=next->x; x--){
+ y = (int32_t)(current->y + (x - current->x) * beta);
+ if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
+ }
+ }
+ }
+ if (current->y != next->y){
+ beta = (float)(next->x - current->x)/(float)(next->y - current->y);
+ if (current->y < next->y){
+ for (y=current->y; y<=next->y; y++){
+ x = (int32_t)(current->x + (y - current->y) * beta);
+ if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
+ }
+ } else {
+ for (y=current->y; y>=next->y; y--){
+ x = (int32_t)(current->x + (y - current->y) * beta);
+ if (IsInside(x,y)) plocal[x + y * head.biWidth] = 255;
+ }
+ }
+ }
+ }
+
+ RECT r2;
+ if (current->x < next->x) {r2.left=current->x; r2.right=next->x; } else {r2.left=next->x ; r2.right=current->x; }
+ if (current->y < next->y) {r2.bottom=current->y; r2.top=next->y; } else {r2.bottom=next->y ; r2.top=current->y; }
+ if (localbox.top < r2.top) localbox.top = max(0L,min(head.biHeight-1,r2.top+1));
+ if (localbox.left > r2.left) localbox.left = max(0L,min(head.biWidth-1,r2.left-1));
+ if (localbox.right < r2.right) localbox.right = max(0L,min(head.biWidth-1,r2.right+1));
+ if (localbox.bottom > r2.bottom) localbox.bottom = max(0L,min(head.biHeight-1,r2.bottom-1));
+
+ i++;
+ }
+
+ //fill the outer region
+ int32_t npix=(localbox.right - localbox.left)*(localbox.top - localbox.bottom);
+ POINT* pix = (POINT*)calloc(npix,sizeof(POINT));
+ uint8_t back=0, mark=1;
+ int32_t fx, fy, fxx, fyy, first, last;
+ int32_t xmin = 0;
+ int32_t xmax = 0;
+ int32_t ymin = 0;
+ int32_t ymax = 0;
+
+ for (int32_t side=0; side<4; side++){
+ switch(side){
+ case 0:
+ xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.bottom+1;
+ break;
+ case 1:
+ xmin=localbox.right; xmax=localbox.right+1; ymin=localbox.bottom; ymax=localbox.top+1;
+ break;
+ case 2:
+ xmin=localbox.left; xmax=localbox.right+1; ymin=localbox.top; ymax=localbox.top+1;
+ break;
+ case 3:
+ xmin=localbox.left; xmax=localbox.left+1; ymin=localbox.bottom; ymax=localbox.top+1;
+ break;
+ }
+ //fill from the border points
+ for(y=ymin;y<ymax;y++){
+ for(x=xmin;x<xmax;x++){
+ if (plocal[x+y*head.biWidth]==0){
+ // Subject: FLOOD FILL ROUTINE Date: 12-23-97 (00:57)
+ // Author: Petter Holmberg Code: QB, QBasic, PDS
+ // Origin: petter.holmberg@usa.net Packet: GRAPHICS.ABC
+ first=0;
+ last=1;
+ while(first!=last){
+ fx = pix[first].x;
+ fy = pix[first].y;
+ fxx = fx + x;
+ fyy = fy + y;
+ for(;;)
+ {
+ if ((plocal[fxx + fyy*head.biWidth] == back) &&
+ fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
+ {
+ plocal[fxx + fyy*head.biWidth] = mark;
+ if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
+ pix[last].x = fx;
+ pix[last].y = fy - 1;
+ last++;
+ if (last == npix) last = 0;
+ }
+ if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
+ pix[last].x = fx;
+ pix[last].y = fy + 1;
+ last++;
+ if (last == npix) last = 0;
+ }
+ } else {
+ break;
+ }
+ fx++;
+ fxx++;
+ };
+
+ fx = pix[first].x - 1;
+ fy = pix[first].y;
+ fxx = fx + x;
+ fyy = fy + y;
+
+ for( ;; )
+ {
+ if ((plocal[fxx + fyy*head.biWidth] == back) &&
+ fxx>=localbox.left && fxx<=localbox.right && fyy>=localbox.bottom && fyy<=localbox.top )
+ {
+ plocal[fxx + (y + fy)*head.biWidth] = mark;
+ if (fyy > 0 && plocal[fxx + (fyy - 1)*head.biWidth] == back){
+ pix[last].x = fx;
+ pix[last].y = fy - 1;
+ last++;
+ if (last == npix) last = 0;
+ }
+ if ((fyy + 1)<head.biHeight && plocal[fxx + (fyy + 1)*head.biWidth] == back){
+ pix[last].x = fx;
+ pix[last].y = fy + 1;
+ last++;
+ if (last == npix) last = 0;
+ }
+ } else {
+ break;
+ }
+ fx--;
+ fxx--;
+ }
+
+ first++;
+ if (first == npix) first = 0;
+ }
+ }
+ }
+ }
+ }
+
+ //transfer the region
+ int32_t yoffset;
+ for (y=localbox.bottom; y<=localbox.top; y++){
+ yoffset = y * head.biWidth;
+ for (x=localbox.left; x<=localbox.right; x++)
+ if (plocal[x + yoffset]!=1) pSelection[x + yoffset]=level;
+ }
+ if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = min(head.biHeight,localbox.top + 1);
+ if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = min(head.biWidth,localbox.left);
+ if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = min(head.biWidth,localbox.right + 1);
+ if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = min(head.biHeight,localbox.bottom);
+
+ free(plocal);
+ free(pix);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds to the selection all the pixels matching the specified color.
+ */
+bool CxImage::SelectionAddColor(RGBQUAD c, uint8_t level)
+{
+ if (pSelection==NULL) SelectionCreate();
+ if (pSelection==NULL) return false;
+
+ RECT localbox = {head.biWidth,0,0,head.biHeight};
+
+ for (int32_t y = 0; y < head.biHeight; y++){
+ for (int32_t x = 0; x < head.biWidth; x++){
+ RGBQUAD color = BlindGetPixelColor(x, y);
+ if (color.rgbRed == c.rgbRed &&
+ color.rgbGreen == c.rgbGreen &&
+ color.rgbBlue == c.rgbBlue)
+ {
+ pSelection[x + y * head.biWidth] = level;
+
+ if (localbox.top < y) localbox.top = y;
+ if (localbox.left > x) localbox.left = x;
+ if (localbox.right < x) localbox.right = x;
+ if (localbox.bottom > y) localbox.bottom = y;
+ }
+ }
+ }
+
+ if (info.rSelectionBox.top <= localbox.top) info.rSelectionBox.top = localbox.top + 1;
+ if (info.rSelectionBox.left > localbox.left) info.rSelectionBox.left = localbox.left;
+ if (info.rSelectionBox.right <= localbox.right) info.rSelectionBox.right = localbox.right + 1;
+ if (info.rSelectionBox.bottom > localbox.bottom) info.rSelectionBox.bottom = localbox.bottom;
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds a single pixel to the existing selection.
+ */
+bool CxImage::SelectionAddPixel(int32_t x, int32_t y, uint8_t level)
+{
+ if (pSelection==NULL) SelectionCreate();
+ if (pSelection==NULL) return false;
+
+ if (IsInside(x,y)) {
+ pSelection[x + y * head.biWidth] = level; // set the correct mask bit
+
+ if (info.rSelectionBox.top <= y) info.rSelectionBox.top = y+1;
+ if (info.rSelectionBox.left > x) info.rSelectionBox.left = x;
+ if (info.rSelectionBox.right <= x) info.rSelectionBox.right = x+1;
+ if (info.rSelectionBox.bottom > y) info.rSelectionBox.bottom = y;
+
+ return true;
+ }
+
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Exports the selection channel in a 8bpp grayscale image.
+ */
+bool CxImage::SelectionSplit(CxImage *dest)
+{
+ if (!pSelection || !dest) return false;
+
+ CxImage tmp(head.biWidth,head.biHeight,8);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ for(int32_t y=0; y<head.biHeight; y++){
+ for(int32_t x=0; x<head.biWidth; x++){
+ tmp.BlindSetPixelIndex(x,y,pSelection[x+y*head.biWidth]);
+ }
+ }
+
+ tmp.SetGrayPalette();
+ dest->Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Creates the selection channel from a gray scale image.
+ * black = unselected
+ */
+bool CxImage::SelectionSet(CxImage &from)
+{
+ if (!from.IsGrayScale() || head.biWidth != from.head.biWidth || head.biHeight != from.head.biHeight){
+ strcpy(info.szLastError,"CxImage::SelectionSet: wrong width or height, or image is not gray scale");
+ return false;
+ }
+
+ if (pSelection==NULL) pSelection = (uint8_t*)malloc(head.biWidth * head.biHeight);
+
+ uint8_t* src = from.info.pImage;
+ uint8_t* dst = pSelection;
+ if (src==NULL || dst==NULL){
+ strcpy(info.szLastError,"CxImage::SelectionSet: null pointer");
+ return false;
+ }
+
+ for (int32_t y=0; y<head.biHeight; y++){
+ memcpy(dst,src,head.biWidth);
+ dst += head.biWidth;
+ src += from.info.dwEffWidth;
+ }
+
+ SelectionRebuildBox();
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Sets the Selection level for a single pixel
+ * internal use only: doesn't set SelectionBox. Use SelectionAddPixel
+ */
+void CxImage::SelectionSet(const int32_t x,const int32_t y,const uint8_t level)
+{
+ if (pSelection && IsInside(x,y)) pSelection[x+y*head.biWidth]=level;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Gets the Selection level for a single pixel
+ */
+uint8_t CxImage::SelectionGet(const int32_t x,const int32_t y)
+{
+ if (pSelection && IsInside(x,y)) return pSelection[x+y*head.biWidth];
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Rebuilds the SelectionBox
+ */
+void CxImage::SelectionRebuildBox()
+{
+ info.rSelectionBox.left = head.biWidth;
+ info.rSelectionBox.bottom = head.biHeight;
+ info.rSelectionBox.right = info.rSelectionBox.top = 0;
+
+ if (!pSelection)
+ return;
+
+ int32_t x,y;
+
+ for (y=0; y<head.biHeight; y++){
+ for (x=0; x<info.rSelectionBox.left; x++){
+ if (pSelection[x+y*head.biWidth]){
+ info.rSelectionBox.left = x;
+ continue;
+ }
+ }
+ }
+
+ for (y=0; y<head.biHeight; y++){
+ for (x=head.biWidth-1; x>=info.rSelectionBox.right; x--){
+ if (pSelection[x+y*head.biWidth]){
+ info.rSelectionBox.right = x+1;
+ continue;
+ }
+ }
+ }
+
+ for (x=0; x<head.biWidth; x++){
+ for (y=0; y<info.rSelectionBox.bottom; y++){
+ if (pSelection[x+y*head.biWidth]){
+ info.rSelectionBox.bottom = y;
+ continue;
+ }
+ }
+ }
+
+ for (x=0; x<head.biWidth; x++){
+ for (y=head.biHeight-1; y>=info.rSelectionBox.top; y--){
+ if (pSelection[x+y*head.biWidth]){
+ info.rSelectionBox.top = y+1;
+ continue;
+ }
+ }
+ }
+
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Gets the Selection level for a single pixel
+ * "blind" version assumes that (x,y) is inside to the image.
+ */
+uint8_t CxImage::BlindSelectionGet(const int32_t x,const int32_t y)
+{
+#ifdef _DEBUG
+ if (!IsInside(x,y) || (pSelection==0))
+ #if CXIMAGE_SUPPORT_EXCEPTION_HANDLING
+ throw 0;
+ #else
+ return 0;
+ #endif
+#endif
+ return pSelection[x+y*head.biWidth];
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Returns pointer to selection data for pixel (x,y).
+ */
+uint8_t* CxImage::SelectionGetPointer(const int32_t x,const int32_t y)
+{
+ if (pSelection && IsInside(x,y)) return pSelection+x+y*head.biWidth;
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::SelectionFlip()
+{
+ if (!pSelection) return false;
+
+ uint8_t *buff = (uint8_t*)malloc(head.biWidth);
+ if (!buff) return false;
+
+ uint8_t *iSrc,*iDst;
+ iSrc = pSelection + (head.biHeight-1)*head.biWidth;
+ iDst = pSelection;
+ for (int32_t i=0; i<(head.biHeight/2); ++i)
+ {
+ memcpy(buff, iSrc, head.biWidth);
+ memcpy(iSrc, iDst, head.biWidth);
+ memcpy(iDst, buff, head.biWidth);
+ iSrc-=head.biWidth;
+ iDst+=head.biWidth;
+ }
+
+ free(buff);
+
+ int32_t top = info.rSelectionBox.top;
+ info.rSelectionBox.top = head.biHeight - info.rSelectionBox.bottom;
+ info.rSelectionBox.bottom = head.biHeight - top;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::SelectionMirror()
+{
+ if (!pSelection) return false;
+ uint8_t* pSelection2 = (uint8_t*)malloc(head.biWidth * head.biHeight);
+ if (!pSelection2) return false;
+
+ uint8_t *iSrc,*iDst;
+ int32_t wdt=head.biWidth-1;
+ iSrc=pSelection + wdt;
+ iDst=pSelection2;
+ for(int32_t y=0; y < head.biHeight; y++){
+ for(int32_t x=0; x <= wdt; x++)
+ *(iDst+x)=*(iSrc-x);
+ iSrc+=head.biWidth;
+ iDst+=head.biWidth;
+ }
+ free(pSelection);
+ pSelection=pSelection2;
+
+ int32_t left = info.rSelectionBox.left;
+ info.rSelectionBox.left = head.biWidth - info.rSelectionBox.right;
+ info.rSelectionBox.right = head.biWidth - left;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_WINDOWS
+/**
+ * Converts the selection in a HRGN object.
+ */
+bool CxImage::SelectionToHRGN(HRGN& region)
+{
+ if (pSelection && region){
+ for(int32_t y = 0; y < head.biHeight; y++){
+ HRGN hTemp = NULL;
+ int32_t iStart = -1;
+ int32_t x = 0;
+ for(; x < head.biWidth; x++){
+ if (pSelection[x + y * head.biWidth] != 0){
+ if (iStart == -1) iStart = x;
+ continue;
+ }else{
+ if (iStart >= 0){
+ hTemp = CreateRectRgn(iStart, y, x, y + 1);
+ CombineRgn(region, hTemp, region, RGN_OR);
+ DeleteObject(hTemp);
+ iStart = -1;
+ }
+ }
+ }
+ if (iStart >= 0){
+ hTemp = CreateRectRgn(iStart, y, x, y + 1);
+ CombineRgn(region, hTemp, region, RGN_OR);
+ DeleteObject(hTemp);
+ iStart = -1;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+#endif //CXIMAGE_SUPPORT_WINDOWS
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_SELECTION
diff --git a/archive/hge/CxImage/ximaska.cpp b/archive/hge/CxImage/ximaska.cpp new file mode 100644 index 0000000..6f1b1c2 --- /dev/null +++ b/archive/hge/CxImage/ximaska.cpp @@ -0,0 +1,126 @@ +/*
+ * File: ximaska.cpp
+ * Purpose: Platform Independent SKA Image Class Loader and Writer
+ * 25/Sep/2007 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximaska.h"
+
+#if CXIMAGE_SUPPORT_SKA
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageSKA::Decode(CxFile *hFile)
+{
+ if (hFile==NULL)
+ return false;
+
+ // read the header
+ SKAHEADER ska_header;
+ hFile->Read(&ska_header,sizeof(SKAHEADER),1);
+
+ ska_header.Width = m_ntohs(ska_header.Width);
+ ska_header.Height = m_ntohs(ska_header.Height);
+ ska_header.dwUnknown = m_ntohl(ska_header.dwUnknown);
+
+ // check header
+ if (ska_header.dwUnknown != 0x01000000 ||
+ ska_header.Width > 0x7FFF || ska_header.Height > 0x7FFF ||
+ ska_header.BppExp != 3)
+ return false;
+
+ if (info.nEscape == -1){
+ head.biWidth = ska_header.Width ;
+ head.biHeight= ska_header.Height;
+ info.dwType = CXIMAGE_FORMAT_SKA;
+ return true;
+ }
+
+ int32_t bpp = 1<<ska_header.BppExp;
+
+ Create(ska_header.Width,ska_header.Height,bpp,CXIMAGE_FORMAT_SKA);
+ if (!IsValid())
+ return false;
+
+ // read the palette
+ int32_t nColors = 1<<bpp;
+ rgb_color* ppal = (rgb_color*)malloc(nColors*sizeof(rgb_color));
+ if (!ppal) return false;
+ hFile->Read(ppal,nColors*sizeof(rgb_color),1);
+ SetPalette(ppal,nColors);
+ free(ppal);
+
+ //read the image
+ hFile->Read(GetBits(),ska_header.Width*ska_header.Height,1);
+
+ //reorder rows
+ if (GetEffWidth() != ska_header.Width){
+ uint8_t *src,*dst;
+ src = GetBits() + ska_header.Width*(ska_header.Height-1);
+ dst = GetBits(ska_header.Height-1);
+ for(int32_t y=0;y<ska_header.Height;y++){
+ memcpy(dst,src,ska_header.Width);
+ src -= ska_header.Width;
+ dst -= GetEffWidth();
+ }
+ }
+
+ Flip();
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageSKA::Encode(CxFile * hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ if(head.biBitCount > 8) {
+ strcpy(info.szLastError,"SKA Images must be 8 bit or less");
+ return false;
+ }
+
+ SKAHEADER ska_header;
+
+ ska_header.Width = (uint16_t)GetWidth();
+ ska_header.Height = (uint16_t)GetHeight();
+ ska_header.BppExp = 3;
+ ska_header.dwUnknown = 0x01000000;
+
+ ska_header.Width = m_ntohs(ska_header.Width);
+ ska_header.Height = m_ntohs(ska_header.Height);
+ ska_header.dwUnknown = m_ntohl(ska_header.dwUnknown);
+
+ hFile->Write(&ska_header,sizeof(SKAHEADER),1);
+
+ ska_header.Width = m_ntohs(ska_header.Width);
+ ska_header.Height = m_ntohs(ska_header.Height);
+ ska_header.dwUnknown = m_ntohl(ska_header.dwUnknown);
+
+ if (head.biBitCount<8) IncreaseBpp(8);
+
+ rgb_color pal[256];
+ for(int32_t idx=0; idx<256; idx++){
+ GetPaletteColor(idx,&(pal[idx].r),&(pal[idx].g),&(pal[idx].b));
+ }
+
+ hFile->Write(pal,256*sizeof(rgb_color),1);
+
+ uint8_t* src = GetBits(ska_header.Height-1);
+ for(int32_t y=0;y<ska_header.Height;y++){
+ hFile->Write(src,ska_header.Width,1);
+ src -= GetEffWidth();
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_SKA
+
diff --git a/archive/hge/CxImage/ximaska.h b/archive/hge/CxImage/ximaska.h new file mode 100644 index 0000000..ad3f598 --- /dev/null +++ b/archive/hge/CxImage/ximaska.h @@ -0,0 +1,44 @@ +/*
+ * File: ximaska.h
+ * Purpose: SKA Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageSKA (c) 25/Sep/2007 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ * ==========================================================
+ */
+#if !defined(__ximaSKA_h)
+#define __ximaSKA_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_SKA
+
+class CxImageSKA: public CxImage
+{
+#pragma pack(1)
+ typedef struct tagSkaHeader {
+ uint16_t Width;
+ uint16_t Height;
+ uint8_t BppExp;
+ uint32_t dwUnknown;
+} SKAHEADER;
+#pragma pack()
+
+public:
+ CxImageSKA(): CxImage(CXIMAGE_FORMAT_SKA) {}
+
+// bool Load(const char * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_ICO);}
+// bool Save(const char * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_ICO);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximatga.cpp b/archive/hge/CxImage/ximatga.cpp new file mode 100644 index 0000000..f1a762a --- /dev/null +++ b/archive/hge/CxImage/ximatga.cpp @@ -0,0 +1,320 @@ +/*
+ * File: ximatga.cpp
+ * Purpose: Platform Independent TGA Image Class Loader and Writer
+ * 05/Jan/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximatga.h"
+
+#if CXIMAGE_SUPPORT_TGA
+
+#include "ximaiter.h"
+
+// Definitions for image types.
+#define TGA_Null 0
+#define TGA_Map 1
+#define TGA_RGB 2
+#define TGA_Mono 3
+#define TGA_RLEMap 9
+#define TGA_RLERGB 10
+#define TGA_RLEMono 11
+#define TGA_CompMap 32
+#define TGA_CompMap4 33
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageTGA::Decode(CxFile *hFile)
+{
+ if (hFile == NULL) return false;
+
+ TGAHEADER tgaHead;
+
+ cx_try
+ {
+ if (hFile->Read(&tgaHead,sizeof(tgaHead),1)==0)
+ cx_throw("Not a TGA");
+
+ tga_toh(&tgaHead);
+
+ bool bCompressed;
+ switch (tgaHead.ImageType){
+ case TGA_Map:
+ case TGA_RGB:
+ case TGA_Mono:
+ bCompressed = false;
+ break;
+ case TGA_RLEMap:
+ case TGA_RLERGB:
+ case TGA_RLEMono:
+ bCompressed = true;
+ break;
+ default:
+ cx_throw("Unknown TGA image type");
+ }
+
+ if (tgaHead.ImageWidth==0 || tgaHead.ImageHeight==0 || tgaHead.PixelDepth==0 || tgaHead.CmapLength>256)
+ cx_throw("bad TGA header");
+
+ if (tgaHead.PixelDepth!=8 && tgaHead.PixelDepth!=15 && tgaHead.PixelDepth!=16 && tgaHead.PixelDepth!=24 && tgaHead.PixelDepth!=32)
+ cx_throw("bad TGA header");
+
+ if (info.nEscape == -1){
+ head.biWidth = tgaHead.ImageWidth ;
+ head.biHeight= tgaHead.ImageHeight;
+ info.dwType = CXIMAGE_FORMAT_TGA;
+ return true;
+ }
+
+ if (tgaHead.IdLength>0) hFile->Seek(tgaHead.IdLength,SEEK_CUR); //skip descriptor
+
+ Create(tgaHead.ImageWidth, tgaHead.ImageHeight, tgaHead.PixelDepth, CXIMAGE_FORMAT_TGA);
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ if (tgaHead.PixelDepth==32) AlphaCreate(); // Image has alpha channel
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ if (!IsValid()) cx_throw("TGA Create failed");
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ if (tgaHead.CmapType != 0){ // read the palette
+ rgb_color pal[256];
+ hFile->Read(pal,tgaHead.CmapLength*sizeof(rgb_color), 1);
+ for (int32_t i=0;i<tgaHead.CmapLength; i++) SetPaletteColor((uint8_t)i,pal[i].b,pal[i].g,pal[i].r);
+ }
+
+ if (tgaHead.ImageType == TGA_Mono || tgaHead.ImageType == TGA_RLEMono)
+ SetGrayPalette();
+
+ // Bits 4 & 5 of the Image Descriptor byte control the ordering of the pixels.
+ bool bXReversed = ((tgaHead.ImagDesc & 16) == 16);
+ bool bYReversed = ((tgaHead.ImagDesc & 32) == 32);
+
+ CImageIterator iter(this);
+ uint8_t rleLeftover = 255; //for images with illegal packet boundary
+ uint8_t* pDest;
+ for (int32_t y=0; y < tgaHead.ImageHeight; y++){
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ if (hFile == NULL || hFile->Eof()) cx_throw("corrupted TGA");
+
+ if (bYReversed) pDest = iter.GetRow(tgaHead.ImageHeight-y-1);
+ else pDest = iter.GetRow(y);
+
+ if (bCompressed) rleLeftover = ExpandCompressedLine(pDest,&tgaHead,hFile,tgaHead.ImageWidth,y,rleLeftover);
+ else ExpandUncompressedLine (pDest,&tgaHead,hFile,tgaHead.ImageWidth,y,0);
+ }
+
+ if (bXReversed) Mirror();
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (bYReversed && tgaHead.PixelDepth==32) AlphaFlip(); //<lioucr>
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageTGA::Encode(CxFile * hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ if (head.biBitCount<8){
+ strcpy(info.szLastError,"Bit depth must be 8 or 24");
+ return false;
+ }
+
+ TGAHEADER tgaHead;
+
+ tgaHead.IdLength = 0; // Image ID Field Length
+ tgaHead.CmapType = GetPalette()!=0; // Color Map Type
+ tgaHead.ImageType = (head.biBitCount == 8) ? (uint8_t)TGA_Map : (uint8_t)TGA_RGB; // Image Type
+
+ tgaHead.CmapIndex=0; // First Entry Index
+ tgaHead.CmapLength=(head.biBitCount == 8) ? 256 : 0; // Color Map Length
+ tgaHead.CmapEntrySize=(head.biBitCount == 8) ? (uint8_t)24 : (uint8_t)0; // Color Map Entry Size
+
+ tgaHead.X_Origin=0; // X-origin of Image
+ tgaHead.Y_Origin=0; // Y-origin of Image
+ tgaHead.ImageWidth=(uint16_t)head.biWidth; // Image Width
+ tgaHead.ImageHeight=(uint16_t)head.biHeight; // Image Height
+ tgaHead.PixelDepth=(uint8_t)head.biBitCount; // Pixel Depth
+ tgaHead.ImagDesc=0; // Image Descriptor
+
+ if (pAlpha && head.biBitCount==24) tgaHead.PixelDepth=32;
+
+ tga_toh(&tgaHead);
+ hFile->Write(&tgaHead,sizeof(TGAHEADER),1);
+ tga_toh(&tgaHead);
+
+ if (head.biBitCount==8){
+ rgb_color pal[256];
+ RGBQUAD* ppal = GetPalette();
+ for (int32_t i=0;i<256; i++){
+ pal[i].r = ppal[i].rgbBlue;
+ pal[i].g = ppal[i].rgbGreen;
+ pal[i].b = ppal[i].rgbRed;
+ }
+ hFile->Write(&pal,256*sizeof(rgb_color),1);
+ }
+
+ CImageIterator iter(this);
+ uint8_t* pDest;
+ if (pAlpha==0 || head.biBitCount==8){
+ for (int32_t y=0; y < tgaHead.ImageHeight; y++){
+ pDest = iter.GetRow(y);
+ hFile->Write(pDest,tgaHead.ImageWidth * (head.biBitCount >> 3),1);
+ }
+ } else {
+ pDest = (uint8_t*)malloc(4*tgaHead.ImageWidth);
+ RGBQUAD c;
+ for (int32_t y=0; y < tgaHead.ImageHeight; y++){
+ for(int32_t x=0, x4=0;x<tgaHead.ImageWidth;x++, x4+=4){
+ c = BlindGetPixelColor(x,y);
+ pDest[x4+0]=c.rgbBlue;
+ pDest[x4+1]=c.rgbGreen;
+ pDest[x4+2]=c.rgbRed;
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ pDest[x4+3]=AlphaGet(x,y);
+#else
+ pDest[x4+3]=0;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ hFile->Write(pDest,4*tgaHead.ImageWidth,1);
+ }
+ free(pDest);
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+uint8_t CxImageTGA::ExpandCompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, uint8_t rleLeftover)
+{
+ uint8_t rle;
+ int32_t filePos=0;
+ for (int32_t x=0; x<width; ){
+ if (rleLeftover != 255){
+ rle = rleLeftover;
+ rleLeftover = 255;
+ } else {
+ hFile->Read(&rle,1,1);
+ }
+ if (rle & 128) { // RLE-Encoded packet
+ rle -= 127; // Calculate real repeat count.
+ if ((x+rle)>width){
+ rleLeftover = (uint8_t)(128 + (rle - (width - x) - 1));
+ filePos = hFile->Tell();
+ rle = (uint8_t)(width - x);
+ }
+ switch (ptgaHead->PixelDepth)
+ {
+ case 32: {
+ RGBQUAD color;
+ hFile->Read(&color,4,1);
+ for (int32_t ix = 0; ix < rle; ix++){
+ memcpy(&pDest[3*ix],&color,3);
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ AlphaSet(ix+x,y,color.rgbReserved);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ break;
+ }
+ case 24: {
+ rgb_color triple;
+ hFile->Read(&triple,3,1);
+ for (int32_t ix = 0; ix < rle; ix++) memcpy(&pDest[3*ix],&triple,3);
+ break;
+ }
+ case 15:
+ case 16: {
+ uint16_t pixel;
+ hFile->Read(&pixel,2,1);
+ rgb_color triple;
+ triple.r = (uint8_t)(( pixel & 0x1F ) * 8); // red
+ triple.g = (uint8_t)(( pixel >> 2 ) & 0x0F8); // green
+ triple.b = (uint8_t)(( pixel >> 7 ) & 0x0F8); // blue
+ for (int32_t ix = 0; ix < rle; ix++){
+ memcpy(&pDest[3*ix],&triple,3);
+ }
+ break;
+ }
+ case 8: {
+ uint8_t pixel;
+ hFile->Read(&pixel,1,1);
+ for (int32_t ix = 0; ix < rle; ix++) pDest[ix] = pixel;
+ }
+ }
+ if (rleLeftover!=255) hFile->Seek(filePos, SEEK_SET);
+ } else { // Raw packet
+ rle += 1; // Calculate real repeat count.
+ if ((x+rle)>width){
+ rleLeftover = (uint8_t)(rle - (width - x) - 1);
+ rle = (uint8_t)(width - x);
+ }
+ ExpandUncompressedLine(pDest,ptgaHead,hFile,rle,y,x);
+ }
+ if (head.biBitCount == 24) pDest += rle*3; else pDest += rle;
+ x += rle;
+ }
+ return rleLeftover;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageTGA::ExpandUncompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, int32_t xoffset)
+{
+ switch (ptgaHead->PixelDepth){
+ case 8:
+ hFile->Read(pDest,width,1);
+ break;
+ case 15:
+ case 16:{
+ uint8_t* dst=pDest;
+ uint16_t pixel;
+ for (int32_t x=0; x<width; x++){
+ hFile->Read(&pixel,2,1);
+ *dst++ = (uint8_t)(( pixel & 0x1F ) * 8); // blue
+ *dst++ = (uint8_t)(( pixel >> 2 ) & 0x0F8); // green
+ *dst++ = (uint8_t)(( pixel >> 7 ) & 0x0F8); // red
+ }
+ break;
+ }
+ case 24:
+ hFile->Read(pDest,3*width,1);
+ break;
+ case 32:{
+ uint8_t* dst=pDest;
+ for (int32_t x=0; x<width; x++){
+ RGBQUAD pixel;
+ hFile->Read(&pixel,4,1);
+ *dst++ = pixel.rgbBlue;
+ *dst++ = pixel.rgbGreen;
+ *dst++ = pixel.rgbRed;
+#if CXIMAGE_SUPPORT_ALPHA // <vho>
+ AlphaSet(x+xoffset,y,pixel.rgbReserved); //alpha
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ break;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageTGA::tga_toh(TGAHEADER* p)
+{
+ p->CmapIndex = m_ntohs(p->CmapIndex);
+ p->CmapLength = m_ntohs(p->CmapLength);
+ p->X_Origin = m_ntohs(p->X_Origin);
+ p->Y_Origin = m_ntohs(p->Y_Origin);
+ p->ImageWidth = m_ntohs(p->ImageWidth);
+ p->ImageHeight = m_ntohs(p->ImageHeight);
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_TGA
diff --git a/archive/hge/CxImage/ximatga.h b/archive/hge/CxImage/ximatga.h new file mode 100644 index 0000000..3cbc36a --- /dev/null +++ b/archive/hge/CxImage/ximatga.h @@ -0,0 +1,61 @@ +/*
+ * File: ximatga.h
+ * Purpose: TARGA Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageTGA (c) 05/Jan/2002 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Parts of the code come from Paintlib : Copyright (c) 1996-1998 Ulrich von Zadow
+ * ==========================================================
+ */
+#if !defined(__ximaTGA_h)
+#define __ximaTGA_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_TGA
+
+class CxImageTGA: public CxImage
+{
+#pragma pack(1)
+typedef struct tagTgaHeader
+{
+ uint8_t IdLength; // Image ID Field Length
+ uint8_t CmapType; // Color Map Type
+ uint8_t ImageType; // Image Type
+
+ uint16_t CmapIndex; // First Entry Index
+ uint16_t CmapLength; // Color Map Length
+ uint8_t CmapEntrySize; // Color Map Entry Size
+
+ uint16_t X_Origin; // X-origin of Image
+ uint16_t Y_Origin; // Y-origin of Image
+ uint16_t ImageWidth; // Image Width
+ uint16_t ImageHeight; // Image Height
+ uint8_t PixelDepth; // Pixel Depth
+ uint8_t ImagDesc; // Image Descriptor
+} TGAHEADER;
+#pragma pack()
+
+public:
+ CxImageTGA(): CxImage(CXIMAGE_FORMAT_TGA) {}
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TGA);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TGA);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+protected:
+ uint8_t ExpandCompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, uint8_t rleLeftover);
+ void ExpandUncompressedLine(uint8_t* pDest,TGAHEADER* ptgaHead,CxFile *hFile,int32_t width, int32_t y, int32_t xoffset);
+ void tga_toh(TGAHEADER* p);
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximath.cpp b/archive/hge/CxImage/ximath.cpp new file mode 100644 index 0000000..0175184 --- /dev/null +++ b/archive/hge/CxImage/ximath.cpp @@ -0,0 +1,97 @@ +#include "ximage.h"
+#include "ximath.h"
+#include <math.h>
+
+//this module should contain some classes for geometrical transformations
+//usable with selections, etc... once it's done, that is. :)
+
+CxPoint2::CxPoint2()
+{
+ x=y=0.0f;
+}
+
+CxPoint2::CxPoint2(float const x_, float const y_)
+{
+ x=x_;
+ y=y_;
+}
+
+CxPoint2::CxPoint2(CxPoint2 const &p)
+{
+ x=p.x;
+ y=p.y;
+}
+
+float CxPoint2::Distance(CxPoint2 const p2)
+{
+ return (float)sqrt((x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y));
+}
+
+float CxPoint2::Distance(float const x_, float const y_)
+{
+ return (float)sqrt((x-x_)*(x-x_)+(y-y_)*(y-y_));
+}
+
+CxRect2::CxRect2()
+{
+}
+
+CxRect2::CxRect2(float const x1_, float const y1_, float const x2_, float const y2_)
+{
+ botLeft.x=x1_;
+ botLeft.y=y1_;
+ topRight.x=x2_;
+ topRight.y=y2_;
+}
+
+CxRect2::CxRect2(CxRect2 const &p)
+{
+ botLeft=p.botLeft;
+ topRight=p.topRight;
+}
+
+float CxRect2::Surface() const
+/*
+ * Returns the surface of rectangle.
+ */
+{
+ return (topRight.x-botLeft.x)*(topRight.y-botLeft.y);
+}
+
+CxRect2 CxRect2::CrossSection(CxRect2 const &r2) const
+/*
+ * Returns crossection with another rectangle.
+ */
+{
+ CxRect2 cs;
+ cs.botLeft.x=max(botLeft.x, r2.botLeft.x);
+ cs.botLeft.y=max(botLeft.y, r2.botLeft.y);
+ cs.topRight.x=min(topRight.x, r2.topRight.x);
+ cs.topRight.y=min(topRight.y, r2.topRight.y);
+ if (cs.botLeft.x<=cs.topRight.x && cs.botLeft.y<=cs.topRight.y) {
+ return cs;
+ } else {
+ return CxRect2(0,0,0,0);
+ }//if
+}
+
+CxPoint2 CxRect2::Center() const
+/*
+ * Returns the center point of rectangle.
+ */
+{
+ return CxPoint2((topRight.x+botLeft.x)/2.0f, (topRight.y+botLeft.y)/2.0f);
+}
+
+float CxRect2::Width() const
+//returns rectangle width
+{
+ return topRight.x-botLeft.x;
+}
+
+float CxRect2::Height() const
+//returns rectangle height
+{
+ return topRight.y-botLeft.y;
+}
+
diff --git a/archive/hge/CxImage/ximath.h b/archive/hge/CxImage/ximath.h new file mode 100644 index 0000000..014c14b --- /dev/null +++ b/archive/hge/CxImage/ximath.h @@ -0,0 +1,39 @@ +#if !defined(__ximath_h)
+#define __ximath_h
+
+#include "ximadef.h"
+
+//***bd*** simple floating point point
+class DLL_EXP CxPoint2
+{
+public:
+ CxPoint2();
+ CxPoint2(float const x_, float const y_);
+ CxPoint2(CxPoint2 const &p);
+
+ float Distance(CxPoint2 const p2);
+ float Distance(float const x_, float const y_);
+
+ float x,y;
+};
+
+//and simple rectangle
+class DLL_EXP CxRect2
+{
+public:
+ CxRect2();
+ CxRect2(float const x1_, float const y1_, float const x2_, float const y2_);
+ CxRect2(CxPoint2 const &bl, CxPoint2 const &tr);
+ CxRect2(CxRect2 const &p);
+
+ float Surface() const;
+ CxRect2 CrossSection(CxRect2 const &r2) const;
+ CxPoint2 Center() const;
+ float Width() const;
+ float Height() const;
+
+ CxPoint2 botLeft;
+ CxPoint2 topRight;
+};
+
+#endif
diff --git a/archive/hge/CxImage/ximatif.cpp b/archive/hge/CxImage/ximatif.cpp new file mode 100644 index 0000000..7675361 --- /dev/null +++ b/archive/hge/CxImage/ximatif.cpp @@ -0,0 +1,982 @@ +/*
+ * File: ximatif.cpp
+ * Purpose: Platform Independent TIFF Image Class Loader and Writer
+ * 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximatif.h"
+
+#if CXIMAGE_SUPPORT_TIF
+
+#define FIX_16BPP_DARKIMG // + VK: if uncomment, dark 16bpp images are fixed
+
+#include "../tiff/tiffio.h"
+
+#define CVT(x) (((x) * 255L) / ((1L<<16)-1))
+#define SCALE(x) (((x)*((1L<<16)-1))/255)
+#define CalculateLine(width,bitdepth) (((width * bitdepth) + 7) / 8)
+#define CalculatePitch(line) (line + 3 & ~3)
+
+extern "C" TIFF* _TIFFOpenEx(CxFile* stream, const char* mode);
+
+////////////////////////////////////////////////////////////////////////////////
+CxImageTIF::~CxImageTIF()
+{
+ if (m_tif2) TIFFClose(m_tif2);
+}
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageTIF::Decode(CxFile * hFile)
+{
+ //Comment this line if you need more information on errors
+ // TIFFSetErrorHandler(NULL); //<Patrick Hoffmann>
+
+ //Open file and fill the TIFF structure
+ // m_tif = TIFFOpen(imageFileName,"rb");
+ TIFF* m_tif = _TIFFOpenEx(hFile, "rb");
+
+ uint32 height=0;
+ uint32 width=0;
+ uint16 bitspersample=1;
+ uint16 samplesperpixel=1;
+ uint32 rowsperstrip=(uint32_t)-1;
+ uint16 photometric=0;
+ uint16 compression=1;
+ uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
+ uint16 res_unit; //<Trifon>
+ uint32 x, y;
+ float resolution, offset;
+ BOOL isRGB;
+ uint8_t *bits; //pointer to source data
+ uint8_t *bits2; //pointer to destination data
+
+ cx_try
+ {
+ //check if it's a tiff file
+ if (!m_tif)
+ cx_throw("Error encountered while opening TIFF file");
+
+ // <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping
+ // info.nNumFrames=0;
+ // while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++;
+ info.nNumFrames = TIFFNumberOfDirectories(m_tif);
+
+ if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame))
+ cx_throw("Error: page not present in TIFF file");
+
+ //get image info
+ TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width);
+ TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height);
+ TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
+ TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
+ TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+ TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric);
+ TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation);
+
+ if (info.nEscape == -1) {
+ // Return output dimensions only
+ head.biWidth = width;
+ head.biHeight = height;
+ info.dwType = CXIMAGE_FORMAT_TIF;
+ cx_throw("output dimensions returned");
+ }
+
+ TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
+ if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution))
+ {
+ if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
+ SetXDPI((int32_t)resolution);
+ }
+ if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
+ {
+ if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
+ SetYDPI((int32_t)resolution);
+ }
+
+ if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset)) info.xOffset = (int32_t)offset;
+ if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset)) info.yOffset = (int32_t)offset;
+
+ head.biClrUsed=0;
+ info.nBkgndIndex =-1;
+
+ if (rowsperstrip>height){
+ rowsperstrip=height;
+ TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+ }
+
+ isRGB = /*(bitspersample >= 8) && (VK: it is possible so for RGB to have < 8 bpp!)*/
+ (photometric == PHOTOMETRIC_RGB) ||
+ (photometric == PHOTOMETRIC_YCBCR) ||
+ (photometric == PHOTOMETRIC_SEPARATED) ||
+ (photometric == PHOTOMETRIC_LOGL) ||
+ (photometric == PHOTOMETRIC_LOGLUV);
+
+ if (isRGB){
+ head.biBitCount=24;
+ }else{
+ if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)||(photometric==PHOTOMETRIC_PALETTE)){
+ if (bitspersample == 1){
+ head.biBitCount=1; //B&W image
+ head.biClrUsed =2;
+ } else if (bitspersample == 4) {
+ head.biBitCount=4; //16 colors gray scale
+ head.biClrUsed =16;
+ } else {
+ head.biBitCount=8; //gray scale
+ head.biClrUsed =256;
+ }
+ } else if (bitspersample == 4) {
+ head.biBitCount=4; // 16 colors
+ head.biClrUsed=16;
+ } else {
+ head.biBitCount=8; //256 colors
+ head.biClrUsed=256;
+ }
+
+ if ((bitspersample > 8) && (photometric==PHOTOMETRIC_PALETTE)) // + VK + (BIG palette! => convert to RGB)
+ { head.biBitCount=24;
+ head.biClrUsed =0;
+ }
+ }
+
+ if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding
+
+ Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF); //image creation
+ if (!pDib) cx_throw("CxImageTIF can't create image");
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (samplesperpixel==4) AlphaCreate(); //add alpha support for 32bpp tiffs
+ if (samplesperpixel==2 && bitspersample==8) AlphaCreate(); //add alpha support for 8bpp + alpha
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
+ SetCodecOption(compression); // <DPR> save original compression type
+
+ if (isRGB) {
+ // Read the whole image into one big RGBA buffer using
+ // the traditional TIFFReadRGBAImage() API that we trust.
+ uint32* raster; // retrieve RGBA image
+ uint32 *row;
+
+ raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32));
+ if (raster == NULL) cx_throw("No space for raster buffer");
+
+ // Read the image in one chunk into an RGBA array
+ if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) {
+ _TIFFfree(raster);
+ cx_throw("Corrupted TIFF file!");
+ }
+
+ // read the raster lines and save them in the DIB
+ // with RGB mode, we have to change the order of the 3 samples RGB
+ row = &raster[0];
+ bits2 = info.pImage;
+ for (y = 0; y < height; y++) {
+
+ if (info.nEscape){ // <vho> - cancel decoding
+ _TIFFfree(raster);
+ cx_throw("Cancelled");
+ }
+
+ bits = bits2;
+ for (x = 0; x < width; x++) {
+ *bits++ = (uint8_t)TIFFGetB(row[x]);
+ *bits++ = (uint8_t)TIFFGetG(row[x]);
+ *bits++ = (uint8_t)TIFFGetR(row[x]);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (samplesperpixel==4) AlphaSet(x,y,(uint8_t)TIFFGetA(row[x]));
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ row += width;
+ bits2 += info.dwEffWidth;
+ }
+ _TIFFfree(raster);
+ } else {
+ int32_t BIG_palette = (bitspersample > 8) && // + VK
+ (photometric==PHOTOMETRIC_PALETTE);
+ if (BIG_palette && (bitspersample > 24)) // + VK
+ cx_throw("Too big palette to handle"); // + VK
+
+ RGBQUAD *pal;
+ pal=(RGBQUAD*)calloc(BIG_palette ? 1<<bitspersample : 256,sizeof(RGBQUAD));
+ // ! VK: it coasts nothing but more correct to use 256 as temp palette storage
+ // ! VK: but for case of BIG palette it just copied
+ if (pal==NULL) cx_throw("Unable to allocate TIFF palette");
+
+ int32_t bpp = bitspersample <= 8 ? bitspersample : 8; // + VK (to use instead of bitspersample for case of > 8)
+
+ // set up the colormap based on photometric
+ switch(photometric) {
+ case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types
+ case PHOTOMETRIC_MINISWHITE:
+ if (bitspersample == 1) { // Monochrome image
+ if (photometric == PHOTOMETRIC_MINISBLACK) {
+ pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
+ } else {
+ pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
+ }
+ } else { // need to build the scale for greyscale images
+ if (photometric == PHOTOMETRIC_MINISBLACK) {
+ for (int32_t i=0; i<(1<<bpp); i++){
+ pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(i*(255/((1<<bpp)-1)));
+ }
+ } else {
+ for (int32_t i=0; i<(1<<bpp); i++){
+ pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(255-i*(255/((1<<bpp)-1)));
+ }
+ }
+ }
+ break;
+ case PHOTOMETRIC_PALETTE: // color map indexed
+ uint16 *red;
+ uint16 *green;
+ uint16 *blue;
+ TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue);
+
+ // Is the palette 16 or 8 bits ?
+ BOOL Palette16Bits = /*FALSE*/ BIG_palette;
+ if (!BIG_palette) {
+ int32_t n= 1<<bpp;
+ while (n-- > 0) {
+ if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) {
+ Palette16Bits=TRUE;
+ break;
+ }
+ }
+ }
+
+ // load the palette in the DIB
+ for (int32_t i = (1 << ( BIG_palette ? bitspersample : bpp )) - 1; i >= 0; i--) {
+ if (Palette16Bits) {
+ pal[i].rgbRed =(uint8_t) CVT(red[i]);
+ pal[i].rgbGreen = (uint8_t) CVT(green[i]);
+ pal[i].rgbBlue = (uint8_t) CVT(blue[i]);
+ } else {
+ pal[i].rgbRed = (uint8_t) red[i];
+ pal[i].rgbGreen = (uint8_t) green[i];
+ pal[i].rgbBlue = (uint8_t) blue[i];
+ }
+ }
+ break;
+ }
+ if (!BIG_palette) { // + VK (BIG palette is stored until image is ready)
+ SetPalette(pal,/*head.biClrUsed*/ 1<<bpp); //palette assign // * VK
+ free(pal);
+ pal = NULL;
+ }
+
+ // read the tiff lines and save them in the DIB
+ uint32 nrow;
+ uint32 ys;
+ int32_t line = CalculateLine(width, bitspersample * samplesperpixel);
+
+ int32_t bitsize = TIFFStripSize(m_tif);
+ //verify bitsize: could be wrong if StripByteCounts is missing.
+ if (bitsize>(int32_t)(head.biSizeImage*samplesperpixel))
+ bitsize = head.biSizeImage*samplesperpixel;
+ if (bitsize<(int32_t)(info.dwEffWidth*rowsperstrip))
+ bitsize = info.dwEffWidth*rowsperstrip;
+
+ if ((bitspersample > 8) && (bitspersample != 16)) // + VK (for bitspersample == 9..15,17..32..64
+ bitsize *= (bitspersample + 7)/8;
+
+ int32_t tiled_image = TIFFIsTiled(m_tif);
+ uint32 tw=0, tl=0;
+ uint8_t* tilebuf=NULL;
+ if (tiled_image){
+ TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
+ TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
+ rowsperstrip = tl;
+ bitsize = TIFFTileSize(m_tif) * (int32_t)(1+width/tw);
+ tilebuf = (uint8_t*)malloc(TIFFTileSize(m_tif));
+ }
+
+ bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK
+ uint8_t * bits16 = NULL; // + VK
+ int32_t line16 = 0; // + VK
+
+ if (!tiled_image && bitspersample==16) { // + VK +
+ line16 = line;
+ line = CalculateLine(width, 8 * samplesperpixel);
+ bits16 = bits;
+ bits = (uint8_t*)malloc(bitsize);
+ }
+
+ if (bits==NULL){
+ if (bits16) free(bits16); // + VK
+ if (pal) free(pal); // + VK
+ if (tilebuf)free(tilebuf); // + VK
+ cx_throw("CxImageTIF can't allocate memory");
+ }
+
+#ifdef FIX_16BPP_DARKIMG // + VK: for each line, store shift count bits used to fix it
+ uint8_t* row_shifts = NULL;
+ if (bits16) row_shifts = (uint8_t*)malloc(height);
+#endif
+
+ for (ys = 0; ys < height; ys += rowsperstrip) {
+
+ if (info.nEscape){ // <vho> - cancel decoding
+ free(bits);
+ cx_throw("Cancelled");
+ }
+
+ nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);
+
+ if (tiled_image){
+ uint32 imagew = TIFFScanlineSize(m_tif);
+ uint32 tilew = TIFFTileRowSize(m_tif);
+ int32_t iskew = imagew - tilew;
+ uint8* bufp = (uint8*) bits;
+
+ uint32 colb = 0;
+ for (uint32 col = 0; col < width; col += tw) {
+ if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){
+ free(tilebuf);
+ free(bits);
+ cx_throw("Corrupted tiled TIFF file!");
+ }
+
+ if (colb + tw > imagew) {
+ uint32 owidth = imagew - colb;
+ uint32 oskew = tilew - owidth;
+ TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew );
+ } else {
+ TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0);
+ }
+ colb += tilew;
+ }
+
+ } else {
+ if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0),
+ (bits16? bits16 : bits), nrow * (bits16 ? line16 : line)) == -1) { // * VK
+
+#ifdef NOT_IGNORE_CORRUPTED
+ free(bits);
+ if (bits16) free(bits16); // + VK
+ cx_throw("Corrupted TIFF file!");
+#else
+ break;
+#endif
+ }
+ }
+
+ for (y = 0; y < nrow; y++) {
+ int32_t offset=(nrow-y-1)*line;
+ if ((bitspersample==16) && !BIG_palette) { // * VK
+ int32_t offset16 = (nrow-y-1)*line16; // + VK
+ if (bits16) { // + VK +
+#ifdef FIX_16BPP_DARKIMG
+ int32_t the_shift;
+ uint8_t hi_byte, hi_max=0;
+ uint32_t xi;
+ for (xi=0;xi<(uint32)line;xi++) {
+ hi_byte = bits16[xi*2+offset16+1];
+ if(hi_byte>hi_max)
+ hi_max = hi_byte;
+ }
+ the_shift = (hi_max == 0) ? 8 : 0;
+ if (!the_shift)
+ while( ! (hi_max & 0x80) ) {
+ the_shift++;
+ hi_max <<= 1;
+ }
+ row_shifts[height-ys-nrow+y] = the_shift;
+ the_shift = 8 - the_shift;
+ for (xi=0;xi<(uint32)line;xi++)
+ bits[xi+offset]= ((bits16[xi*2+offset16+1]<<8) | bits16[xi*2+offset16]) >> the_shift;
+#else
+ for (uint32_t xi=0;xi<(uint32)line;xi++)
+ bits[xi+offset]=bits16[xi*2+offset16+1];
+#endif
+ } else {
+ for (uint32_t xi=0;xi<width;xi++)
+ bits[xi+offset]=bits[xi*2+offset+1];
+ }
+ }
+ if (samplesperpixel==1) {
+ if (BIG_palette)
+ if (bits16) {
+ int32_t offset16 = (nrow-y-1)*line16; // + VK
+ MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
+ bits16 + offset16, width, bitspersample, pal );
+ } else
+ MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
+ bits + offset, width, bitspersample, pal );
+ else if ((bitspersample == head.biBitCount) ||
+ (bitspersample == 16)) //simple 8bpp, 4bpp image or 16bpp
+ memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,min((unsigned)line, info.dwEffWidth));
+ else
+ MoveBits( info.pImage + info.dwEffWidth * (height-ys-nrow+y),
+ bits + offset, width, bitspersample );
+ } else if (samplesperpixel==2) { //8bpp image with alpha layer
+ int32_t xi=0;
+ int32_t ii=0;
+ int32_t yi=height-ys-nrow+y;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (!pAlpha) AlphaCreate(); // + VK
+#endif //CXIMAGE_SUPPORT_ALPHA
+ while (ii<line){
+ SetPixelIndex(xi,yi,bits[ii+offset]);
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaSet(xi,yi,bits[ii+offset+1]);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ ii+=2;
+ xi++;
+ if (xi>=(int32_t)width){
+ yi--;
+ xi=0;
+ }
+ }
+ } else { //photometric==PHOTOMETRIC_CIELAB
+ if (head.biBitCount!=24){ //fix image
+ Create(width,height,24,CXIMAGE_FORMAT_TIF);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (samplesperpixel==4) AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+
+ int32_t xi=0;
+ uint32 ii=0;
+ int32_t yi=height-ys-nrow+y;
+ RGBQUAD c;
+ int32_t l,a,b,bitsoffset;
+ double p,cx,cy,cz,cr,cg,cb;
+ while (ii</*line*/width){ // * VK
+ bitsoffset = ii*samplesperpixel+offset;
+ l=bits[bitsoffset];
+ a=bits[bitsoffset+1];
+ b=bits[bitsoffset+2];
+ if (a>127) a-=256;
+ if (b>127) b-=256;
+ // lab to xyz
+ p = (l/2.55 + 16) / 116.0;
+ cx = pow( p + a * 0.002, 3);
+ cy = pow( p, 3);
+ cz = pow( p - b * 0.005, 3);
+ // white point
+ cx*=0.95047;
+ //cy*=1.000;
+ cz*=1.0883;
+ // xyz to rgb
+ cr = 3.240479 * cx - 1.537150 * cy - 0.498535 * cz;
+ cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz;
+ cb = 0.055648 * cx - 0.204043 * cy + 1.057311 * cz;
+
+ if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055;
+ else cr = 12.92 * cr;
+ if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055;
+ else cg = 12.92 * cg;
+ if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055;
+ else cb = 12.92 * cb;
+
+ c.rgbRed =(uint8_t)max(0,min(255,(int32_t)(cr*255)));
+ c.rgbGreen=(uint8_t)max(0,min(255,(int32_t)(cg*255)));
+ c.rgbBlue =(uint8_t)max(0,min(255,(int32_t)(cb*255)));
+
+ SetPixelColor(xi,yi,c);
+#if CXIMAGE_SUPPORT_ALPHA
+ if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ ii++;
+ xi++;
+ if (xi>=(int32_t)width){
+ yi--;
+ xi=0;
+ }
+ }
+ }
+ }
+ }
+ free(bits);
+ if (bits16) free(bits16);
+
+#ifdef FIX_16BPP_DARKIMG
+ if (row_shifts && (samplesperpixel == 1) && (bitspersample==16) && !BIG_palette) {
+ // 1. calculate maximum necessary shift
+ int32_t min_row_shift = 8;
+ for( y=0; y<height; y++ ) {
+ if (min_row_shift > row_shifts[y]) min_row_shift = row_shifts[y];
+ }
+ // 2. for rows having less shift value, correct such rows:
+ for( y=0; y<height; y++ ) {
+ if (min_row_shift < row_shifts[y]) {
+ int32_t need_shift = row_shifts[y] - min_row_shift;
+ uint8_t* data = info.pImage + info.dwEffWidth * y;
+ for( x=0; x<width; x++, data++ )
+ *data >>= need_shift;
+ }
+ }
+ }
+ if (row_shifts) free( row_shifts );
+#endif
+
+ if (tiled_image) free(tilebuf);
+ if (pal) free(pal);
+
+ switch(orientation){
+ case ORIENTATION_TOPRIGHT: /* row 0 top, col 0 rhs */
+ Mirror();
+ break;
+ case ORIENTATION_BOTRIGHT: /* row 0 bottom, col 0 rhs */
+ Flip();
+ Mirror();
+ break;
+ case ORIENTATION_BOTLEFT: /* row 0 bottom, col 0 lhs */
+ Flip();
+ break;
+ case ORIENTATION_LEFTTOP: /* row 0 lhs, col 0 top */
+ RotateRight();
+ Mirror();
+ break;
+ case ORIENTATION_RIGHTTOP: /* row 0 rhs, col 0 top */
+ RotateLeft();
+ break;
+ case ORIENTATION_RIGHTBOT: /* row 0 rhs, col 0 bottom */
+ RotateLeft();
+ Mirror();
+ break;
+ case ORIENTATION_LEFTBOT: /* row 0 lhs, col 0 bottom */
+ RotateRight();
+ break;
+ }
+
+ }
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (m_tif) TIFFClose(m_tif);
+ if (info.nEscape == -1 && info.dwType == CXIMAGE_FORMAT_TIF) return true;
+ return false;
+ }
+ TIFFClose(m_tif);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageTIF::Encode(CxFile * hFile, bool bAppend)
+{
+ cx_try
+ {
+ if (hFile==NULL) cx_throw(CXIMAGE_ERR_NOFILE);
+ if (pDib==NULL) cx_throw(CXIMAGE_ERR_NOIMAGE);
+
+ // <RJ> replaced "w+b" with "a", to append an image directly on an existing file
+ if (m_tif2==NULL) m_tif2=_TIFFOpenEx(hFile, "a");
+ if (m_tif2==NULL) cx_throw("initialization fail");
+
+ if (bAppend || m_pages) m_multipage=true;
+ m_pages++;
+
+ if (!EncodeBody(m_tif2,m_multipage,m_pages,m_pages)) cx_throw("Error saving TIFF file");
+ if (bAppend) {
+ if (!TIFFWriteDirectory(m_tif2)) cx_throw("Error saving TIFF directory");
+ }
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ if (m_tif2){
+ TIFFClose(m_tif2);
+ m_tif2=NULL;
+ m_multipage=false;
+ m_pages=0;
+ }
+ return false;
+ }
+ if (!bAppend){
+ TIFFClose(m_tif2);
+ m_tif2=NULL;
+ m_multipage=false;
+ m_pages=0;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+// Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
+bool CxImageTIF::Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount)
+{
+ cx_try
+ {
+ if (hFile==NULL) cx_throw("invalid file pointer");
+ if (pImages==NULL || pagecount<=0) cx_throw("multipage TIFF, no images!");
+
+ int32_t i;
+ for (i=0; i<pagecount; i++){
+ if (pImages[i]==NULL)
+ cx_throw("Bad image pointer");
+ if (!(pImages[i]->IsValid()))
+ cx_throw("Empty image");
+ }
+
+ CxImageTIF ghost;
+ for (i=0; i<pagecount; i++){
+ ghost.Ghost(pImages[i]);
+ if (!ghost.Encode(hFile,true)) cx_throw("Error saving TIFF file");
+ }
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return false;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int32_t page, int32_t pagecount)
+{
+ uint32 height=head.biHeight;
+ uint32 width=head.biWidth;
+ uint16 bitcount=head.biBitCount;
+ uint16 bitspersample;
+ uint16 samplesperpixel;
+ uint16 photometric=0;
+ uint16 compression;
+// uint16 pitch;
+// int32_t line;
+ uint32 x, y;
+
+ samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (uint8_t)3 : (uint8_t)1;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (bitcount==24 && AlphaIsValid()) { bitcount=32; samplesperpixel=4; }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ bitspersample = bitcount / samplesperpixel;
+
+ //set the PHOTOMETRIC tag
+ RGBQUAD *rgb = GetPalette();
+ switch (bitcount) {
+ case 1:
+ if (CompareColors(&rgb[0],&rgb[1])<0) {
+ /* <abe> some viewers do not handle PHOTOMETRIC_MINISBLACK:
+ * let's transform the image in PHOTOMETRIC_MINISWHITE
+ */
+ //invert the colors
+ RGBQUAD tempRGB=GetPaletteColor(0);
+ SetPaletteColor(0,GetPaletteColor(1));
+ SetPaletteColor(1,tempRGB);
+ //invert the pixels
+ uint8_t *iSrc=info.pImage;
+ for (uint32_t i=0;i<head.biSizeImage;i++){
+ *iSrc=(uint8_t)~(*(iSrc));
+ iSrc++;
+ }
+ photometric = PHOTOMETRIC_MINISWHITE;
+ //photometric = PHOTOMETRIC_MINISBLACK;
+ } else {
+ photometric = PHOTOMETRIC_MINISWHITE;
+ }
+ break;
+ case 4: // Check if the DIB has a color or a greyscale palette
+ case 8:
+ photometric = PHOTOMETRIC_MINISBLACK; //default to gray scale
+ for (x = 0; x < head.biClrUsed; x++) {
+ if ((rgb->rgbRed != x)||(rgb->rgbRed != rgb->rgbGreen)||(rgb->rgbRed != rgb->rgbBlue)){
+ photometric = PHOTOMETRIC_PALETTE;
+ break;
+ }
+ rgb++;
+ }
+ break;
+ case 24:
+ case 32:
+ photometric = PHOTOMETRIC_RGB;
+ break;
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid() && bitcount==8) samplesperpixel=2; //8bpp + alpha layer
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+// line = CalculateLine(width, bitspersample * samplesperpixel);
+// pitch = (uint16)CalculatePitch(line);
+
+ //prepare the palette struct
+ RGBQUAD pal[256];
+ if (GetPalette()){
+ uint8_t b;
+ memcpy(pal,GetPalette(),GetPaletteSize());
+ for(uint16_t a=0;a<head.biClrUsed;a++){ //swap blue and red components
+ b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b;
+ }
+ }
+
+ // handle standard width/height/bpp stuff
+ TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width);
+ TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height);
+ TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+ TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
+ TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric);
+ TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane
+ TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+
+ uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1); //<REC> gives better compression
+ TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+
+ // handle metrics
+ TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
+ TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)info.xDPI);
+ TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)info.yDPI);
+// TIFFSetField(m_tif, TIFFTAG_XPOSITION, (float)info.xOffset);
+// TIFFSetField(m_tif, TIFFTAG_YPOSITION, (float)info.yOffset);
+
+ // multi-paging - Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
+ if (multipage)
+ {
+ char page_number[20];
+ sprintf(page_number, "Page %d", page);
+
+ TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
+ TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page,pagecount);
+ TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number);
+ } else {
+ TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0);
+ }
+
+ // palettes (image colormaps are automatically scaled to 16-bits)
+ if (photometric == PHOTOMETRIC_PALETTE) {
+ uint16 *r, *g, *b;
+ r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256);
+ g = r + 256;
+ b = g + 256;
+
+ for (int32_t i = 255; i >= 0; i--) {
+ b[i] = (uint16)SCALE((uint16)pal[i].rgbRed);
+ g[i] = (uint16)SCALE((uint16)pal[i].rgbGreen);
+ r[i] = (uint16)SCALE((uint16)pal[i].rgbBlue);
+ }
+
+ TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b);
+ _TIFFfree(r);
+ }
+
+ // compression
+ if (GetCodecOption(CXIMAGE_FORMAT_TIF)) {
+ compression = (uint16_t)GetCodecOption(CXIMAGE_FORMAT_TIF);
+ } else {
+ switch (bitcount) {
+ case 1 :
+ compression = COMPRESSION_CCITTFAX4;
+ break;
+ case 4 :
+ case 8 :
+ compression = COMPRESSION_LZW;
+ break;
+ case 24 :
+ case 32 :
+ compression = COMPRESSION_JPEG;
+ break;
+ default :
+ compression = COMPRESSION_NONE;
+ break;
+ }
+ }
+ TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);
+
+ switch (compression) {
+ case COMPRESSION_JPEG:
+ TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, GetJpegQuality());
+ TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, ((7+rowsperstrip)>>3)<<3);
+ break;
+ case COMPRESSION_LZW:
+ if (bitcount>=8) TIFFSetField(m_tif, TIFFTAG_PREDICTOR, 2);
+ break;
+ }
+
+ // read the DIB lines from bottom to top and save them in the TIF
+
+ uint8_t *bits;
+ switch(bitcount) {
+ case 1 :
+ case 4 :
+ case 8 :
+ {
+ if (samplesperpixel==1){
+ bits = (uint8_t*)malloc(info.dwEffWidth);
+ if (!bits) return false;
+ for (y = 0; y < height; y++) {
+ memcpy(bits,info.pImage + (height - y - 1)*info.dwEffWidth,info.dwEffWidth);
+ if (TIFFWriteScanline(m_tif,bits, y, 0)==-1){
+ free(bits);
+ return false;
+ }
+ }
+ free(bits);
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ else { //8bpp + alpha layer
+ bits = (uint8_t*)malloc(2*width);
+ if (!bits) return false;
+ for (y = 0; y < height; y++) {
+ for (x=0;x<width;x++){
+ bits[2*x]=BlindGetPixelIndex(x,height - y - 1);
+ bits[2*x+1]=AlphaGet(x,height - y - 1);
+ }
+ if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) {
+ free(bits);
+ return false;
+ }
+ }
+ free(bits);
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+ break;
+ }
+ case 24:
+ {
+ uint8_t *buffer = (uint8_t *)malloc(info.dwEffWidth);
+ if (!buffer) return false;
+ for (y = 0; y < height; y++) {
+ // get a pointer to the scanline
+ memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
+ // TIFFs store color data RGB instead of BGR
+ uint8_t *pBuf = buffer;
+ for (x = 0; x < width; x++) {
+ uint8_t tmp = pBuf[0];
+ pBuf[0] = pBuf[2];
+ pBuf[2] = tmp;
+ pBuf += 3;
+ }
+ // write the scanline to disc
+ if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
+ free(buffer);
+ return false;
+ }
+ }
+ free(buffer);
+ break;
+ }
+ case 32 :
+ {
+#if CXIMAGE_SUPPORT_ALPHA
+ uint8_t *buffer = (uint8_t *)malloc((info.dwEffWidth*4)/3);
+ if (!buffer) return false;
+ for (y = 0; y < height; y++) {
+ // get a pointer to the scanline
+ memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
+ // TIFFs store color data RGB instead of BGR
+ uint8_t *pSrc = buffer + 3 * width;
+ uint8_t *pDst = buffer + 4 * width;
+ for (x = 0; x < width; x++) {
+ pDst-=4;
+ pSrc-=3;
+ pDst[3] = AlphaGet(width-x-1,height-y-1);
+ pDst[2] = pSrc[0];
+ pDst[1] = pSrc[1];
+ pDst[0] = pSrc[2];
+ }
+ // write the scanline to disc
+ if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
+ free(buffer);
+ return false;
+ }
+ }
+ free(buffer);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ break;
+ }
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+void CxImageTIF::TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int32_t outskew, int32_t inskew)
+{
+ while (rows-- > 0) {
+ uint32 j = cols;
+ while (j-- > 0)
+ *out++ = *in++;
+ out += outskew;
+ in += inskew;
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+TIFF* CxImageTIF::TIFFOpenEx(CxFile * hFile)
+{
+ if (hFile) return _TIFFOpenEx(hFile, "rb");
+ return NULL;
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageTIF::TIFFCloseEx(TIFF* tif)
+{
+ if (tif) TIFFClose(tif);
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageTIF::MoveBits( uint8_t* dest, uint8_t* from, int32_t count, int32_t bpp )
+{ int32_t offbits = 0;
+ uint16 w;
+ uint32 d;
+ if (bpp <= 8) {
+ while (count-- > 0) {
+ if (offbits + bpp <= 8)
+ w = *from >> (8 - offbits - bpp);
+ else {
+ w = *from++ << (offbits + bpp - 8);
+ w |= *from >> (16 - offbits - bpp);
+ }
+ offbits += bpp;
+ if (offbits >= 8) {
+ offbits -= 8;
+ if (offbits == 0) from++;
+ }
+ *dest++ = (uint8_t)w & ((1 << bpp)-1);
+ }
+ } else if (bpp < 16) {
+ while (count-- > 0) {
+ d = (*from << 24) | (from[1]<<16) | (from[2]<<8) | from[3];
+ d >>= (24 - offbits);
+ *dest++ = (uint8_t) ( d );
+ offbits += bpp;
+ while (offbits >= 8) {
+ from++;
+ offbits -= 8;
+ }
+ }
+ } else if (bpp < 32) {
+ while (count-- > 0) {
+ d = (*from << 24) | (from[1]<<16) | (from[2]<<8) | from[3];
+ //d = *(uint32*)from;
+ *dest++ = (uint8_t) ( d >> (offbits + bpp - 8) );
+ offbits += bpp;
+ while (offbits >= 8) {
+ from++;
+ offbits -= 8;
+ }
+ }
+ } else {
+ while (count-- > 0) {
+ d = *(uint32*)from;
+ *dest++ = (uint8_t) (d >> 24);
+ from += 4;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+void CxImageTIF::MoveBitsPal( uint8_t* dest, uint8_t*from, int32_t count, int32_t bpp, RGBQUAD* pal )
+{ int32_t offbits = 0;
+ uint32 d;
+ uint16 palidx;
+ while (count-- > 0) {
+ d = (*from << 24) | ( *( from + 1 ) << 16 )
+ | ( *( from + 2 ) << 8 )
+ | ( *( from + 3 ) );
+ palidx = (uint16) (d >> (32 - offbits - bpp));
+ if (bpp < 16) {
+ palidx <<= 16-bpp;
+ palidx = (palidx >> 8) | (palidx <<8);
+ palidx >>= 16-bpp;
+ } else palidx = (palidx >> 8) | (palidx << 8);
+ *dest++ = pal[palidx].rgbBlue;
+ *dest++ = pal[palidx].rgbGreen;
+ *dest++ = pal[palidx].rgbRed;
+ offbits += bpp;
+ while (offbits >= 8) {
+ from++;
+ offbits -= 8;
+ }
+ }
+}
+////////////////////////////////////////////////////////////////////////////////
+
+#endif // CXIMAGE_SUPPORT_TIF
diff --git a/archive/hge/CxImage/ximatif.h b/archive/hge/CxImage/ximatif.h new file mode 100644 index 0000000..5ea31f0 --- /dev/null +++ b/archive/hge/CxImage/ximatif.h @@ -0,0 +1,62 @@ +/*
+ * File: ximatif.h
+ * Purpose: TIFF Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageTIF (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ *
+ * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
+ *
+ * Special thanks to Abe <God(dot)bless(at)marihuana(dot)com> for MultiPageTIFF code.
+ *
+ * LibTIFF is:
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ * ==========================================================
+ */
+
+#if !defined(__ximatif_h)
+#define __ximatif_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_TIF
+
+#include "../tiff/tiffio.h"
+
+class DLL_EXP CxImageTIF: public CxImage
+{
+public:
+ CxImageTIF(): CxImage(CXIMAGE_FORMAT_TIF) {m_tif2=NULL; m_multipage=false; m_pages=0;}
+ ~CxImageTIF();
+
+ TIFF* TIFFOpenEx(CxFile * hFile);
+ void TIFFCloseEx(TIFF* tif);
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_TIF);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_TIF);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile, bool bAppend=false);
+ bool Encode(CxFile * hFile, CxImage ** pImages, int32_t pagecount);
+ bool Encode(FILE *hFile, bool bAppend=false) { CxIOFile file(hFile); return Encode(&file,bAppend); }
+ bool Encode(FILE *hFile, CxImage ** pImages, int32_t pagecount)
+ { CxIOFile file(hFile); return Encode(&file, pImages, pagecount); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+protected:
+ void TileToStrip(uint8* out, uint8* in, uint32 rows, uint32 cols, int32_t outskew, int32_t inskew);
+ bool EncodeBody(TIFF *m_tif, bool multipage=false, int32_t page=0, int32_t pagecount=0);
+ TIFF *m_tif2;
+ bool m_multipage;
+ int32_t m_pages;
+ void MoveBits( uint8_t* dest, uint8_t* from, int32_t count, int32_t bpp );
+ void MoveBitsPal( uint8_t* dest, uint8_t*from, int32_t count, int32_t bpp, RGBQUAD* pal );
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximatran.cpp b/archive/hge/CxImage/ximatran.cpp new file mode 100644 index 0000000..decac18 --- /dev/null +++ b/archive/hge/CxImage/ximatran.cpp @@ -0,0 +1,2728 @@ +// xImaTran.cpp : Transformation functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+#include "ximath.h"
+
+#if CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Increases the number of bits per pixel of the image.
+ * \param nbit: 4, 8, 24
+ */
+bool CxImage::IncreaseBpp(uint32_t nbit)
+{
+ if (!pDib) return false;
+ switch (nbit){
+ case 4:
+ {
+ if (head.biBitCount==4) return true;
+ if (head.biBitCount>4) return false;
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(head.biWidth,head.biHeight,4,info.dwType);
+ tmp.SetPalette(GetPalette(),GetNumColors());
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+
+#if CXIMAGE_SUPPORT_SELECTION
+ tmp.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaCopy(*this);
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ tmp.BlindSetPixelIndex(x,y,BlindGetPixelIndex(x,y));
+ }
+ }
+ Transfer(tmp);
+ return true;
+ }
+ case 8:
+ {
+ if (head.biBitCount==8) return true;
+ if (head.biBitCount>8) return false;
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(head.biWidth,head.biHeight,8,info.dwType);
+ tmp.SetPalette(GetPalette(),GetNumColors());
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+#if CXIMAGE_SUPPORT_SELECTION
+ tmp.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaCopy(*this);
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ tmp.BlindSetPixelIndex(x,y,BlindGetPixelIndex(x,y));
+ }
+ }
+ Transfer(tmp);
+ return true;
+ }
+ case 24:
+ {
+ if (head.biBitCount==24) return true;
+ if (head.biBitCount>24) return false;
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(head.biWidth,head.biHeight,24,info.dwType);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ if (info.nBkgndIndex>=0) //translate transparency
+ tmp.info.nBkgndColor=GetPaletteColor((uint8_t)info.nBkgndIndex);
+
+#if CXIMAGE_SUPPORT_SELECTION
+ tmp.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaCopy(*this);
+ if (AlphaPaletteIsValid() && !AlphaIsValid()) tmp.AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ tmp.BlindSetPixelColor(x,y,BlindGetPixelColor(x,y),true);
+ }
+ }
+ Transfer(tmp);
+ return true;
+ }
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::GrayScale()
+{
+ if (!pDib) return false;
+ if (head.biBitCount<=8){
+ RGBQUAD* ppal=GetPalette();
+ int32_t gray;
+ //converts the colors to gray, use the blue channel only
+ for(uint32_t i=0;i<head.biClrUsed;i++){
+ gray=(int32_t)RGB2GRAY(ppal[i].rgbRed,ppal[i].rgbGreen,ppal[i].rgbBlue);
+ ppal[i].rgbBlue = (uint8_t)gray;
+ }
+ // preserve transparency
+ if (info.nBkgndIndex >= 0) info.nBkgndIndex = ppal[info.nBkgndIndex].rgbBlue;
+ //create a "real" 8 bit gray scale image
+ if (head.biBitCount==8){
+ uint8_t *img=info.pImage;
+ for(uint32_t i=0;i<head.biSizeImage;i++) img[i]=ppal[img[i]].rgbBlue;
+ SetGrayPalette();
+ }
+ //transform to 8 bit gray scale
+ if (head.biBitCount==4 || head.biBitCount==1){
+ CxImage ima;
+ ima.CopyInfo(*this);
+ if (!ima.Create(head.biWidth,head.biHeight,8,info.dwType)) return false;
+ ima.SetGrayPalette();
+#if CXIMAGE_SUPPORT_SELECTION
+ ima.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+#if CXIMAGE_SUPPORT_ALPHA
+ ima.AlphaCopy(*this);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ for (int32_t y=0;y<head.biHeight;y++){
+ uint8_t *iDst = ima.GetBits(y);
+ uint8_t *iSrc = GetBits(y);
+ for (int32_t x=0;x<head.biWidth; x++){
+ //iDst[x]=ppal[BlindGetPixelIndex(x,y)].rgbBlue;
+ if (head.biBitCount==4){
+ uint8_t pos = (uint8_t)(4*(1-x%2));
+ iDst[x]= ppal[(uint8_t)((iSrc[x >> 1]&((uint8_t)0x0F<<pos)) >> pos)].rgbBlue;
+ } else {
+ uint8_t pos = (uint8_t)(7-x%8);
+ iDst[x]= ppal[(uint8_t)((iSrc[x >> 3]&((uint8_t)0x01<<pos)) >> pos)].rgbBlue;
+ }
+ }
+ }
+ Transfer(ima);
+ }
+ } else { //from RGB to 8 bit gray scale
+ uint8_t *iSrc=info.pImage;
+ CxImage ima;
+ ima.CopyInfo(*this);
+ if (!ima.Create(head.biWidth,head.biHeight,8,info.dwType)) return false;
+ ima.SetGrayPalette();
+ if (GetTransIndex()>=0){
+ RGBQUAD c = GetTransColor();
+ ima.SetTransIndex((uint8_t)RGB2GRAY(c.rgbRed,c.rgbGreen,c.rgbBlue));
+ }
+#if CXIMAGE_SUPPORT_SELECTION
+ ima.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+#if CXIMAGE_SUPPORT_ALPHA
+ ima.AlphaCopy(*this);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ uint8_t *img=ima.GetBits();
+ int32_t l8=ima.GetEffWidth();
+ int32_t l=head.biWidth * 3;
+ for(int32_t y=0; y < head.biHeight; y++) {
+ for(int32_t x=0,x8=0; x < l; x+=3,x8++) {
+ img[x8+y*l8]=(uint8_t)RGB2GRAY(*(iSrc+x+2),*(iSrc+x+1),*(iSrc+x+0));
+ }
+ iSrc+=info.dwEffWidth;
+ }
+ Transfer(ima);
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa Mirror
+ * \author [qhbo]
+ */
+bool CxImage::Flip(bool bFlipSelection, bool bFlipAlpha)
+{
+ if (!pDib) return false;
+
+ uint8_t *buff = (uint8_t*)malloc(info.dwEffWidth);
+ if (!buff) return false;
+
+ uint8_t *iSrc,*iDst;
+ iSrc = GetBits(head.biHeight-1);
+ iDst = GetBits(0);
+ for (int32_t i=0; i<(head.biHeight/2); ++i)
+ {
+ memcpy(buff, iSrc, info.dwEffWidth);
+ memcpy(iSrc, iDst, info.dwEffWidth);
+ memcpy(iDst, buff, info.dwEffWidth);
+ iSrc-=info.dwEffWidth;
+ iDst+=info.dwEffWidth;
+ }
+
+ free(buff);
+
+ if (bFlipSelection){
+#if CXIMAGE_SUPPORT_SELECTION
+ SelectionFlip();
+#endif //CXIMAGE_SUPPORT_SELECTION
+ }
+
+ if (bFlipAlpha){
+#if CXIMAGE_SUPPORT_ALPHA
+ AlphaFlip();
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \sa Flip
+ */
+bool CxImage::Mirror(bool bMirrorSelection, bool bMirrorAlpha)
+{
+ if (!pDib) return false;
+
+ CxImage* imatmp = new CxImage(*this,false,true,true);
+ if (!imatmp) return false;
+ if (!imatmp->IsValid()){
+ delete imatmp;
+ return false;
+ }
+
+ uint8_t *iSrc,*iDst;
+ int32_t wdt=(head.biWidth-1) * (head.biBitCount==24 ? 3:1);
+ iSrc=info.pImage + wdt;
+ iDst=imatmp->info.pImage;
+ int32_t x,y;
+ switch (head.biBitCount){
+ case 24:
+ for(y=0; y < head.biHeight; y++){
+ for(x=0; x <= wdt; x+=3){
+ *(iDst+x)=*(iSrc-x);
+ *(iDst+x+1)=*(iSrc-x+1);
+ *(iDst+x+2)=*(iSrc-x+2);
+ }
+ iSrc+=info.dwEffWidth;
+ iDst+=info.dwEffWidth;
+ }
+ break;
+ case 8:
+ for(y=0; y < head.biHeight; y++){
+ for(x=0; x <= wdt; x++)
+ *(iDst+x)=*(iSrc-x);
+ iSrc+=info.dwEffWidth;
+ iDst+=info.dwEffWidth;
+ }
+ break;
+ default:
+ for(y=0; y < head.biHeight; y++){
+ for(x=0; x <= wdt; x++)
+ imatmp->SetPixelIndex(x,y,GetPixelIndex(wdt-x,y));
+ }
+ }
+
+ if (bMirrorSelection){
+#if CXIMAGE_SUPPORT_SELECTION
+ imatmp->SelectionMirror();
+#endif //CXIMAGE_SUPPORT_SELECTION
+ }
+
+ if (bMirrorAlpha){
+#if CXIMAGE_SUPPORT_ALPHA
+ imatmp->AlphaMirror();
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+
+ Transfer(*imatmp);
+ delete imatmp;
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#define RBLOCK 64
+
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::RotateLeft(CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ int32_t newWidth = GetHeight();
+ int32_t newHeight = GetWidth();
+
+ CxImage imgDest;
+ imgDest.CopyInfo(*this);
+ imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
+ imgDest.SetPalette(GetPalette());
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) imgDest.AlphaCreate();
+#endif
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()) imgDest.SelectionCreate();
+#endif
+
+ int32_t x,x2,y,dlineup;
+
+ // Speedy rotate for BW images <Robert Abram>
+ if (head.biBitCount == 1) {
+
+ uint8_t *sbits, *dbits, *dbitsmax, bitpos, *nrow,*srcdisp;
+ ldiv_t div_r;
+
+ uint8_t *bsrc = GetBits(), *bdest = imgDest.GetBits();
+ dbitsmax = bdest + imgDest.head.biSizeImage - 1;
+ dlineup = 8 * imgDest.info.dwEffWidth - imgDest.head.biWidth;
+
+ imgDest.Clear(0);
+ for (y = 0; y < head.biHeight; y++) {
+ // Figure out the Column we are going to be copying to
+ div_r = ldiv(y + dlineup, (int32_t)8);
+ // set bit pos of src column byte
+ bitpos = (uint8_t)(1 << div_r.rem);
+ srcdisp = bsrc + y * info.dwEffWidth;
+ for (x = 0; x < (int32_t)info.dwEffWidth; x++) {
+ // Get Source Bits
+ sbits = srcdisp + x;
+ // Get destination column
+ nrow = bdest + (x * 8) * imgDest.info.dwEffWidth + imgDest.info.dwEffWidth - 1 - div_r.quot;
+ for (int32_t z = 0; z < 8; z++) {
+ // Get Destination Byte
+ dbits = nrow + z * imgDest.info.dwEffWidth;
+ if ((dbits < bdest) || (dbits > dbitsmax)) break;
+ if (*sbits & (128 >> z)) *dbits |= bitpos;
+ }
+ }
+ }//for y
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) {
+ for (x = 0; x < newWidth; x++){
+ x2=newWidth-x-1;
+ for (y = 0; y < newHeight; y++){
+ imgDest.AlphaSet(x,y,BlindAlphaGet(y, x2));
+ }//for y
+ }//for x
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()) {
+ imgDest.info.rSelectionBox.left = newWidth-info.rSelectionBox.top;
+ imgDest.info.rSelectionBox.right = newWidth-info.rSelectionBox.bottom;
+ imgDest.info.rSelectionBox.bottom = info.rSelectionBox.left;
+ imgDest.info.rSelectionBox.top = info.rSelectionBox.right;
+ for (x = 0; x < newWidth; x++){
+ x2=newWidth-x-1;
+ for (y = 0; y < newHeight; y++){
+ imgDest.SelectionSet(x,y,BlindSelectionGet(y, x2));
+ }//for y
+ }//for x
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ } else {
+ //anything other than BW:
+ //bd, 10. 2004: This optimized version of rotation rotates image by smaller blocks. It is quite
+ //a bit faster than obvious algorithm, because it produces much less CPU cache misses.
+ //This optimization can be tuned by changing block size (RBLOCK). 96 is good value for current
+ //CPUs (tested on Athlon XP and Celeron D). Larger value (if CPU has enough cache) will increase
+ //speed somehow, but once you drop out of CPU's cache, things will slow down drastically.
+ //For older CPUs with less cache, lower value would yield better results.
+
+ uint8_t *srcPtr, *dstPtr; //source and destionation for 24-bit version
+ int32_t xs, ys; //x-segment and y-segment
+ for (xs = 0; xs < newWidth; xs+=RBLOCK) { //for all image blocks of RBLOCK*RBLOCK pixels
+ for (ys = 0; ys < newHeight; ys+=RBLOCK) {
+ if (head.biBitCount==24) {
+ //RGB24 optimized pixel access:
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){ //do rotation
+ info.nProgress = (int32_t)(100*x/newWidth);
+ x2=newWidth-x-1;
+ dstPtr = (uint8_t*) imgDest.BlindGetPixelPointer(x,ys);
+ srcPtr = (uint8_t*) BlindGetPixelPointer(ys, x2);
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ //imgDest.SetPixelColor(x, y, GetPixelColor(y, x2));
+ *(dstPtr) = *(srcPtr);
+ *(dstPtr+1) = *(srcPtr+1);
+ *(dstPtr+2) = *(srcPtr+2);
+ srcPtr += 3;
+ dstPtr += imgDest.info.dwEffWidth;
+ }//for y
+ }//for x
+ } else {
+ //anything else than 24bpp (and 1bpp): palette
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ info.nProgress = (int32_t)(100*x/newWidth); //<Anatoly Ivasyuk>
+ x2=newWidth-x-1;
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ imgDest.SetPixelIndex(x, y, BlindGetPixelIndex(y, x2));
+ }//for y
+ }//for x
+ }//if (version selection)
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) {
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ x2=newWidth-x-1;
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ imgDest.AlphaSet(x,y,BlindAlphaGet(y, x2));
+ }//for y
+ }//for x
+ }//if (alpha channel)
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()) {
+ imgDest.info.rSelectionBox.left = newWidth-info.rSelectionBox.top;
+ imgDest.info.rSelectionBox.right = newWidth-info.rSelectionBox.bottom;
+ imgDest.info.rSelectionBox.bottom = info.rSelectionBox.left;
+ imgDest.info.rSelectionBox.top = info.rSelectionBox.right;
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ x2=newWidth-x-1;
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ imgDest.SelectionSet(x,y,BlindSelectionGet(y, x2));
+ }//for y
+ }//for x
+ }//if (selection)
+#endif //CXIMAGE_SUPPORT_SELECTION
+ }//for ys
+ }//for xs
+ }//if
+
+ //select the destination
+ if (iDst) iDst->Transfer(imgDest);
+ else Transfer(imgDest);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::RotateRight(CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ int32_t newWidth = GetHeight();
+ int32_t newHeight = GetWidth();
+
+ CxImage imgDest;
+ imgDest.CopyInfo(*this);
+ imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
+ imgDest.SetPalette(GetPalette());
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) imgDest.AlphaCreate();
+#endif
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()) imgDest.SelectionCreate();
+#endif
+
+ int32_t x,y,y2;
+ // Speedy rotate for BW images <Robert Abram>
+ if (head.biBitCount == 1) {
+
+ uint8_t *sbits, *dbits, *dbitsmax, bitpos, *nrow,*srcdisp;
+ ldiv_t div_r;
+
+ uint8_t *bsrc = GetBits(), *bdest = imgDest.GetBits();
+ dbitsmax = bdest + imgDest.head.biSizeImage - 1;
+
+ imgDest.Clear(0);
+ for (y = 0; y < head.biHeight; y++) {
+ // Figure out the Column we are going to be copying to
+ div_r = ldiv(y, (int32_t)8);
+ // set bit pos of src column byte
+ bitpos = (uint8_t)(128 >> div_r.rem);
+ srcdisp = bsrc + y * info.dwEffWidth;
+ for (x = 0; x < (int32_t)info.dwEffWidth; x++) {
+ // Get Source Bits
+ sbits = srcdisp + x;
+ // Get destination column
+ nrow = bdest + (imgDest.head.biHeight-1-(x*8)) * imgDest.info.dwEffWidth + div_r.quot;
+ for (int32_t z = 0; z < 8; z++) {
+ // Get Destination Byte
+ dbits = nrow - z * imgDest.info.dwEffWidth;
+ if ((dbits < bdest) || (dbits > dbitsmax)) break;
+ if (*sbits & (128 >> z)) *dbits |= bitpos;
+ }
+ }
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){
+ for (y = 0; y < newHeight; y++){
+ y2=newHeight-y-1;
+ for (x = 0; x < newWidth; x++){
+ imgDest.AlphaSet(x,y,BlindAlphaGet(y2, x));
+ }
+ }
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()){
+ imgDest.info.rSelectionBox.left = info.rSelectionBox.bottom;
+ imgDest.info.rSelectionBox.right = info.rSelectionBox.top;
+ imgDest.info.rSelectionBox.bottom = newHeight-info.rSelectionBox.right;
+ imgDest.info.rSelectionBox.top = newHeight-info.rSelectionBox.left;
+ for (y = 0; y < newHeight; y++){
+ y2=newHeight-y-1;
+ for (x = 0; x < newWidth; x++){
+ imgDest.SelectionSet(x,y,BlindSelectionGet(y2, x));
+ }
+ }
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+ } else {
+ //anything else but BW
+ uint8_t *srcPtr, *dstPtr; //source and destionation for 24-bit version
+ int32_t xs, ys; //x-segment and y-segment
+ for (xs = 0; xs < newWidth; xs+=RBLOCK) {
+ for (ys = 0; ys < newHeight; ys+=RBLOCK) {
+ if (head.biBitCount==24) {
+ //RGB24 optimized pixel access:
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ info.nProgress = (int32_t)(100*y/newHeight); //<Anatoly Ivasyuk>
+ y2=newHeight-y-1;
+ dstPtr = (uint8_t*) imgDest.BlindGetPixelPointer(xs,y);
+ srcPtr = (uint8_t*) BlindGetPixelPointer(y2, xs);
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ //imgDest.SetPixelColor(x, y, GetPixelColor(y2, x));
+ *(dstPtr) = *(srcPtr);
+ *(dstPtr+1) = *(srcPtr+1);
+ *(dstPtr+2) = *(srcPtr+2);
+ dstPtr += 3;
+ srcPtr += info.dwEffWidth;
+ }//for x
+ }//for y
+ } else {
+ //anything else than BW & RGB24: palette
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ info.nProgress = (int32_t)(100*y/newHeight); //<Anatoly Ivasyuk>
+ y2=newHeight-y-1;
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ imgDest.SetPixelIndex(x, y, BlindGetPixelIndex(y2, x));
+ }//for x
+ }//for y
+ }//if
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ y2=newHeight-y-1;
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ imgDest.AlphaSet(x,y,BlindAlphaGet(y2, x));
+ }//for x
+ }//for y
+ }//if (has alpha)
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()){
+ imgDest.info.rSelectionBox.left = info.rSelectionBox.bottom;
+ imgDest.info.rSelectionBox.right = info.rSelectionBox.top;
+ imgDest.info.rSelectionBox.bottom = newHeight-info.rSelectionBox.right;
+ imgDest.info.rSelectionBox.top = newHeight-info.rSelectionBox.left;
+ for (y = ys; y < min(newHeight, ys+RBLOCK); y++){
+ y2=newHeight-y-1;
+ for (x = xs; x < min(newWidth, xs+RBLOCK); x++){
+ imgDest.SelectionSet(x,y,BlindSelectionGet(y2, x));
+ }//for x
+ }//for y
+ }//if (has alpha)
+#endif //CXIMAGE_SUPPORT_SELECTION
+ }//for ys
+ }//for xs
+ }//if
+
+ //select the destination
+ if (iDst) iDst->Transfer(imgDest);
+ else Transfer(imgDest);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Negative()
+{
+ if (!pDib) return false;
+
+ if (head.biBitCount<=8){
+ if (IsGrayScale()){ //GRAYSCALE, selection
+ if (pSelection){
+ for(int32_t y=info.rSelectionBox.bottom; y<info.rSelectionBox.top; y++){
+ for(int32_t x=info.rSelectionBox.left; x<info.rSelectionBox.right; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ BlindSetPixelIndex(x,y,(uint8_t)(255-BlindGetPixelIndex(x,y)));
+ }
+ }
+ }
+ } else {
+ uint8_t *iSrc=info.pImage;
+ for(uint32_t i=0; i < head.biSizeImage; i++){
+ *iSrc=(uint8_t)~(*(iSrc));
+ iSrc++;
+ }
+ }
+ } else { //PALETTE, full image
+ RGBQUAD* ppal=GetPalette();
+ for(uint32_t i=0;i<head.biClrUsed;i++){
+ ppal[i].rgbBlue =(uint8_t)(255-ppal[i].rgbBlue);
+ ppal[i].rgbGreen =(uint8_t)(255-ppal[i].rgbGreen);
+ ppal[i].rgbRed =(uint8_t)(255-ppal[i].rgbRed);
+ }
+ }
+ } else {
+ if (pSelection==NULL){ //RGB, full image
+ uint8_t *iSrc=info.pImage;
+ for(uint32_t i=0; i < head.biSizeImage; i++){
+ *iSrc=(uint8_t)~(*(iSrc));
+ iSrc++;
+ }
+ } else { // RGB with selection
+ RGBQUAD color;
+ for(int32_t y=info.rSelectionBox.bottom; y<info.rSelectionBox.top; y++){
+ for(int32_t x=info.rSelectionBox.left; x<info.rSelectionBox.right; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ color = BlindGetPixelColor(x,y);
+ color.rgbRed = (uint8_t)(255-color.rgbRed);
+ color.rgbGreen = (uint8_t)(255-color.rgbGreen);
+ color.rgbBlue = (uint8_t)(255-color.rgbBlue);
+ BlindSetPixelColor(x,y,color);
+ }
+ }
+ }
+ }
+ //<DP> invert transparent color too
+ info.nBkgndColor.rgbBlue = (uint8_t)(255-info.nBkgndColor.rgbBlue);
+ info.nBkgndColor.rgbGreen = (uint8_t)(255-info.nBkgndColor.rgbGreen);
+ info.nBkgndColor.rgbRed = (uint8_t)(255-info.nBkgndColor.rgbRed);
+ }
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_TRANSFORMATION
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_EXIF
+bool CxImage::RotateExif(int32_t orientation /* = 0 */)
+{
+ bool ret = true;
+ if (orientation <= 0)
+ orientation = info.ExifInfo.Orientation;
+ if (orientation == 3)
+ ret = Rotate180();
+ else if (orientation == 6)
+ ret = RotateRight();
+ else if (orientation == 8)
+ ret = RotateLeft();
+ else if (orientation == 5)
+ ret = RotateLeft();
+
+ info.ExifInfo.Orientation = 1;
+ return ret;
+}
+#endif //CXIMAGE_SUPPORT_EXIF
+
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Rotate(float angle, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ if (fmod(angle,180.0f)==0.0f && fmod(angle,360.0f)!=0.0f)
+ return Rotate180(iDst);
+
+ // Copyright (c) 1996-1998 Ulrich von Zadow
+
+ // Negative the angle, because the y-axis is negative.
+ double ang = -angle*acos((float)0)/90;
+ int32_t newWidth, newHeight;
+ int32_t nWidth = GetWidth();
+ int32_t nHeight= GetHeight();
+ double cos_angle = cos(ang);
+ double sin_angle = sin(ang);
+
+ // Calculate the size of the new bitmap
+ POINT p1={0,0};
+ POINT p2={nWidth,0};
+ POINT p3={0,nHeight};
+ POINT p4={nWidth,nHeight};
+ CxPoint2 newP1,newP2,newP3,newP4, leftTop, rightTop, leftBottom, rightBottom;
+
+ newP1.x = (float)p1.x;
+ newP1.y = (float)p1.y;
+ newP2.x = (float)(p2.x*cos_angle - p2.y*sin_angle);
+ newP2.y = (float)(p2.x*sin_angle + p2.y*cos_angle);
+ newP3.x = (float)(p3.x*cos_angle - p3.y*sin_angle);
+ newP3.y = (float)(p3.x*sin_angle + p3.y*cos_angle);
+ newP4.x = (float)(p4.x*cos_angle - p4.y*sin_angle);
+ newP4.y = (float)(p4.x*sin_angle + p4.y*cos_angle);
+
+ leftTop.x = min(min(newP1.x,newP2.x),min(newP3.x,newP4.x));
+ leftTop.y = min(min(newP1.y,newP2.y),min(newP3.y,newP4.y));
+ rightBottom.x = max(max(newP1.x,newP2.x),max(newP3.x,newP4.x));
+ rightBottom.y = max(max(newP1.y,newP2.y),max(newP3.y,newP4.y));
+ leftBottom.x = leftTop.x;
+ leftBottom.y = rightBottom.y;
+ rightTop.x = rightBottom.x;
+ rightTop.y = leftTop.y;
+
+ newWidth = (int32_t) floor(0.5f + rightTop.x - leftTop.x);
+ newHeight= (int32_t) floor(0.5f + leftBottom.y - leftTop.y);
+ CxImage imgDest;
+ imgDest.CopyInfo(*this);
+ imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
+ imgDest.SetPalette(GetPalette());
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if(AlphaIsValid()) //MTA: Fix for rotation problem when the image has an alpha channel
+ {
+ imgDest.AlphaCreate();
+ imgDest.AlphaClear();
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ int32_t x,y,newX,newY,oldX,oldY;
+
+ if (head.biClrUsed==0){ //RGB
+ for (y = (int32_t)leftTop.y, newY = 0; y<=(int32_t)leftBottom.y; y++,newY++){
+ info.nProgress = (int32_t)(100*newY/newHeight);
+ if (info.nEscape) break;
+ for (x = (int32_t)leftTop.x, newX = 0; x<=(int32_t)rightTop.x; x++,newX++){
+ oldX = (int32_t)(x*cos_angle + y*sin_angle + 0.5);
+ oldY = (int32_t)(y*cos_angle - x*sin_angle + 0.5);
+ imgDest.SetPixelColor(newX,newY,GetPixelColor(oldX,oldY));
+#if CXIMAGE_SUPPORT_ALPHA
+ imgDest.AlphaSet(newX,newY,AlphaGet(oldX,oldY)); //MTA: copy the alpha value
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ } else { //PALETTE
+ for (y = (int32_t)leftTop.y, newY = 0; y<=(int32_t)leftBottom.y; y++,newY++){
+ info.nProgress = (int32_t)(100*newY/newHeight);
+ if (info.nEscape) break;
+ for (x = (int32_t)leftTop.x, newX = 0; x<=(int32_t)rightTop.x; x++,newX++){
+ oldX = (int32_t)(x*cos_angle + y*sin_angle + 0.5);
+ oldY = (int32_t)(y*cos_angle - x*sin_angle + 0.5);
+ imgDest.SetPixelIndex(newX,newY,GetPixelIndex(oldX,oldY));
+#if CXIMAGE_SUPPORT_ALPHA
+ imgDest.AlphaSet(newX,newY,AlphaGet(oldX,oldY)); //MTA: copy the alpha value
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ }
+ //select the destination
+ if (iDst) iDst->Transfer(imgDest);
+ else Transfer(imgDest);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Rotates image around it's center.
+ * Method can use interpolation with paletted images, but does not change pallete, so results vary.
+ * (If you have only four colours in a palette, there's not much room for interpolation.)
+ *
+ * \param angle - angle in degrees (positive values rotate clockwise)
+ * \param *iDst - destination image (if null, this image is changed)
+ * \param inMethod - interpolation method used
+ * (IM_NEAREST_NEIGHBOUR produces aliasing (fast), IM_BILINEAR softens picture a bit (slower)
+ * IM_SHARPBICUBIC is slower and produces some halos...)
+ * \param ofMethod - overflow method (how to choose colour of pixels that have no source)
+ * \param replColor - replacement colour to use (OM_COLOR, OM_BACKGROUND with no background colour...)
+ * \param optimizeRightAngles - call faster methods for 90, 180, and 270 degree rotations. Faster methods
+ * are called for angles, where error (in location of corner pixels) is less
+ * than 0.25 pixels.
+ * \param bKeepOriginalSize - rotates the image without resizing.
+ *
+ * \author ***bd*** 2.2004
+ */
+bool CxImage::Rotate2(float angle,
+ CxImage *iDst,
+ InterpolationMethod inMethod,
+ OverflowMethod ofMethod,
+ RGBQUAD *replColor,
+ bool const optimizeRightAngles,
+ bool const bKeepOriginalSize)
+{
+ if (!pDib) return false; //no dib no go
+
+ if (fmod(angle,180.0f)==0.0f && fmod(angle,360.0f)!=0.0f)
+ return Rotate180(iDst);
+
+ double ang = -angle*acos(0.0f)/90.0f; //convert angle to radians and invert (positive angle performs clockwise rotation)
+ float cos_angle = (float) cos(ang); //these two are needed later (to rotate)
+ float sin_angle = (float) sin(ang);
+
+ //Calculate the size of the new bitmap (rotate corners of image)
+ CxPoint2 p[4]; //original corners of the image
+ p[0]=CxPoint2(-0.5f,-0.5f);
+ p[1]=CxPoint2(GetWidth()-0.5f,-0.5f);
+ p[2]=CxPoint2(-0.5f,GetHeight()-0.5f);
+ p[3]=CxPoint2(GetWidth()-0.5f,GetHeight()-0.5f);
+ CxPoint2 newp[4]; //rotated positions of corners
+ //(rotate corners)
+ if (bKeepOriginalSize){
+ for (int32_t i=0; i<4; i++) {
+ newp[i].x = p[i].x;
+ newp[i].y = p[i].y;
+ }//for
+ } else {
+ for (int32_t i=0; i<4; i++) {
+ newp[i].x = (p[i].x*cos_angle - p[i].y*sin_angle);
+ newp[i].y = (p[i].x*sin_angle + p[i].y*cos_angle);
+ }//for i
+
+ if (optimizeRightAngles) {
+ //For rotations of 90, -90 or 180 or 0 degrees, call faster routines
+ if (newp[3].Distance(CxPoint2(GetHeight()-0.5f, 0.5f-GetWidth())) < 0.25)
+ //rotation right for circa 90 degrees (diagonal pixels less than 0.25 pixel away from 90 degree rotation destination)
+ return RotateRight(iDst);
+ if (newp[3].Distance(CxPoint2(0.5f-GetHeight(), -0.5f+GetWidth())) < 0.25)
+ //rotation left for ~90 degrees
+ return RotateLeft(iDst);
+ if (newp[3].Distance(CxPoint2(0.5f-GetWidth(), 0.5f-GetHeight())) < 0.25)
+ //rotation left for ~180 degrees
+ return Rotate180(iDst);
+ if (newp[3].Distance(p[3]) < 0.25) {
+ //rotation not significant
+ if (iDst) iDst->Copy(*this); //copy image to iDst, if required
+ return true; //and we're done
+ }//if
+ }//if
+ }//if
+
+ //(read new dimensions from location of corners)
+ float minx = (float) min(min(newp[0].x,newp[1].x),min(newp[2].x,newp[3].x));
+ float miny = (float) min(min(newp[0].y,newp[1].y),min(newp[2].y,newp[3].y));
+ float maxx = (float) max(max(newp[0].x,newp[1].x),max(newp[2].x,newp[3].x));
+ float maxy = (float) max(max(newp[0].y,newp[1].y),max(newp[2].y,newp[3].y));
+ int32_t newWidth = (int32_t) floor(maxx-minx+0.5f);
+ int32_t newHeight= (int32_t) floor(maxy-miny+0.5f);
+ float ssx=((maxx+minx)- ((float) newWidth-1))/2.0f; //start for x
+ float ssy=((maxy+miny)- ((float) newHeight-1))/2.0f; //start for y
+
+ float newxcenteroffset = 0.5f * newWidth;
+ float newycenteroffset = 0.5f * newHeight;
+ if (bKeepOriginalSize){
+ ssx -= 0.5f * GetWidth();
+ ssy -= 0.5f * GetHeight();
+ }
+
+ //create destination image
+ CxImage imgDest;
+ imgDest.CopyInfo(*this);
+ imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
+ imgDest.SetPalette(GetPalette());
+#if CXIMAGE_SUPPORT_ALPHA
+ if(AlphaIsValid()) imgDest.AlphaCreate(); //MTA: Fix for rotation problem when the image has an alpha channel
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ RGBQUAD rgb; //pixel colour
+ RGBQUAD rc;
+ if (replColor!=0)
+ rc=*replColor;
+ else {
+ rc.rgbRed=255; rc.rgbGreen=255; rc.rgbBlue=255; rc.rgbReserved=0;
+ }//if
+ float x,y; //destination location (float, with proper offset)
+ float origx, origy; //origin location
+ int32_t destx, desty; //destination location
+
+ y=ssy; //initialize y
+ if (!IsIndexed()){ //RGB24
+ //optimized RGB24 implementation (direct write to destination):
+ uint8_t *pxptr;
+#if CXIMAGE_SUPPORT_ALPHA
+ uint8_t *pxptra=0;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ for (desty=0; desty<newHeight; desty++) {
+ info.nProgress = (int32_t)(100*desty/newHeight);
+ if (info.nEscape) break;
+ //initialize x
+ x=ssx;
+ //calculate pointer to first byte in row
+ pxptr=(uint8_t *)imgDest.BlindGetPixelPointer(0, desty);
+#if CXIMAGE_SUPPORT_ALPHA
+ //calculate pointer to first byte in row
+ if (AlphaIsValid()) pxptra=imgDest.AlphaGetPointer(0, desty);
+#endif //CXIMAGE_SUPPORT_ALPHA
+ for (destx=0; destx<newWidth; destx++) {
+ //get source pixel coordinate for current destination point
+ //origx = (cos_angle*(x-head.biWidth/2)+sin_angle*(y-head.biHeight/2))+newWidth/2;
+ //origy = (cos_angle*(y-head.biHeight/2)-sin_angle*(x-head.biWidth/2))+newHeight/2;
+ origx = cos_angle*x+sin_angle*y;
+ origy = cos_angle*y-sin_angle*x;
+ if (bKeepOriginalSize){
+ origx += newxcenteroffset;
+ origy += newycenteroffset;
+ }
+ rgb = GetPixelColorInterpolated(origx, origy, inMethod, ofMethod, &rc); //get interpolated colour value
+ //copy alpha and colour value to destination
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pxptra) *pxptra++ = rgb.rgbReserved;
+#endif //CXIMAGE_SUPPORT_ALPHA
+ *pxptr++ = rgb.rgbBlue;
+ *pxptr++ = rgb.rgbGreen;
+ *pxptr++ = rgb.rgbRed;
+ x++;
+ }//for destx
+ y++;
+ }//for desty
+ } else {
+ //non-optimized implementation for paletted images
+ for (desty=0; desty<newHeight; desty++) {
+ info.nProgress = (int32_t)(100*desty/newHeight);
+ if (info.nEscape) break;
+ x=ssx;
+ for (destx=0; destx<newWidth; destx++) {
+ //get source pixel coordinate for current destination point
+ origx=(cos_angle*x+sin_angle*y);
+ origy=(cos_angle*y-sin_angle*x);
+ if (bKeepOriginalSize){
+ origx += newxcenteroffset;
+ origy += newycenteroffset;
+ }
+ rgb = GetPixelColorInterpolated(origx, origy, inMethod, ofMethod, &rc);
+ //***!*** SetPixelColor is slow for palleted images
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid())
+ imgDest.SetPixelColor(destx,desty,rgb,true);
+ else
+#endif //CXIMAGE_SUPPORT_ALPHA
+ imgDest.SetPixelColor(destx,desty,rgb,false);
+ x++;
+ }//for destx
+ y++;
+ }//for desty
+ }
+ //select the destination
+
+ if (iDst) iDst->Transfer(imgDest);
+ else Transfer(imgDest);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Rotate180(CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ int32_t wid = GetWidth();
+ int32_t ht = GetHeight();
+
+ CxImage imgDest;
+ imgDest.CopyInfo(*this);
+ imgDest.Create(wid,ht,GetBpp(),GetType());
+ imgDest.SetPalette(GetPalette());
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) imgDest.AlphaCreate();
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ int32_t x,y,y2;
+ for (y = 0; y < ht; y++){
+ info.nProgress = (int32_t)(100*y/ht); //<Anatoly Ivasyuk>
+ y2=ht-y-1;
+ for (x = 0; x < wid; x++){
+ if(head.biClrUsed==0)//RGB
+ imgDest.SetPixelColor(wid-x-1, y2, BlindGetPixelColor(x, y));
+ else //PALETTE
+ imgDest.SetPixelIndex(wid-x-1, y2, BlindGetPixelIndex(x, y));
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) imgDest.AlphaSet(wid-x-1, y2,BlindAlphaGet(x, y));
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ }
+ }
+
+ //select the destination
+ if (iDst) iDst->Transfer(imgDest);
+ else Transfer(imgDest);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Resizes the image. mode can be 0 for slow (bilinear) method ,
+ * 1 for fast (nearest pixel) method, or 2 for accurate (bicubic spline interpolation) method.
+ * The function is faster with 24 and 1 bpp images, slow for 4 bpp images and slowest for 8 bpp images.
+ */
+bool CxImage::Resample(int32_t newx, int32_t newy, int32_t mode, CxImage* iDst)
+{
+ if (newx==0 || newy==0) return false;
+
+ if (head.biWidth==newx && head.biHeight==newy){
+ if (iDst) iDst->Copy(*this);
+ return true;
+ }
+
+ float xScale, yScale, fX, fY;
+ xScale = (float)head.biWidth / (float)newx;
+ yScale = (float)head.biHeight / (float)newy;
+
+ CxImage newImage;
+ newImage.CopyInfo(*this);
+ newImage.Create(newx,newy,head.biBitCount,GetType());
+ newImage.SetPalette(GetPalette());
+ if (!newImage.IsValid()){
+ strcpy(info.szLastError,newImage.GetLastError());
+ return false;
+ }
+
+ switch (mode) {
+ case 1: // nearest pixel
+ {
+ for(int32_t y=0; y<newy; y++){
+ info.nProgress = (int32_t)(100*y/newy);
+ if (info.nEscape) break;
+ fY = y * yScale;
+ for(int32_t x=0; x<newx; x++){
+ fX = x * xScale;
+ newImage.SetPixelColor(x,y,GetPixelColor((int32_t)fX,(int32_t)fY));
+ }
+ }
+ break;
+ }
+ case 2: // bicubic interpolation by Blake L. Carlson <blake-carlson(at)uiowa(dot)edu
+ {
+ float f_x, f_y, a, b, rr, gg, bb, r1, r2;
+ int32_t i_x, i_y, xx, yy;
+ RGBQUAD rgb;
+ uint8_t* iDst;
+ for(int32_t y=0; y<newy; y++){
+ info.nProgress = (int32_t)(100*y/newy);
+ if (info.nEscape) break;
+ f_y = (float) y * yScale - 0.5f;
+ i_y = (int32_t) floor(f_y);
+ a = f_y - (float)floor(f_y);
+ for(int32_t x=0; x<newx; x++){
+ f_x = (float) x * xScale - 0.5f;
+ i_x = (int32_t) floor(f_x);
+ b = f_x - (float)floor(f_x);
+
+ rr = gg = bb = 0.0f;
+ for(int32_t m=-1; m<3; m++) {
+ r1 = KernelBSpline((float) m - a);
+ yy = i_y+m;
+ if (yy<0) yy=0;
+ if (yy>=head.biHeight) yy = head.biHeight-1;
+ for(int32_t n=-1; n<3; n++) {
+ r2 = r1 * KernelBSpline(b - (float)n);
+ xx = i_x+n;
+ if (xx<0) xx=0;
+ if (xx>=head.biWidth) xx=head.biWidth-1;
+
+ if (head.biClrUsed){
+ rgb = GetPixelColor(xx,yy);
+ } else {
+ iDst = info.pImage + yy*info.dwEffWidth + xx*3;
+ rgb.rgbBlue = *iDst++;
+ rgb.rgbGreen= *iDst++;
+ rgb.rgbRed = *iDst;
+ }
+
+ rr += rgb.rgbRed * r2;
+ gg += rgb.rgbGreen * r2;
+ bb += rgb.rgbBlue * r2;
+ }
+ }
+
+ if (head.biClrUsed)
+ newImage.SetPixelColor(x,y,RGB(rr,gg,bb));
+ else {
+ iDst = newImage.info.pImage + y*newImage.info.dwEffWidth + x*3;
+ *iDst++ = (uint8_t)bb;
+ *iDst++ = (uint8_t)gg;
+ *iDst = (uint8_t)rr;
+ }
+
+ }
+ }
+ break;
+ }
+ default: // bilinear interpolation
+ if (!(head.biWidth>newx && head.biHeight>newy && head.biBitCount==24)) {
+ // (c) 1999 Steve McMahon (steve@dogma.demon.co.uk)
+ int32_t ifX, ifY, ifX1, ifY1, xmax, ymax;
+ float ir1, ir2, ig1, ig2, ib1, ib2, dx, dy;
+ uint8_t r,g,b;
+ RGBQUAD rgb1, rgb2, rgb3, rgb4;
+ xmax = head.biWidth-1;
+ ymax = head.biHeight-1;
+ for(int32_t y=0; y<newy; y++){
+ info.nProgress = (int32_t)(100*y/newy);
+ if (info.nEscape) break;
+ fY = y * yScale;
+ ifY = (int32_t)fY;
+ ifY1 = min(ymax, ifY+1);
+ dy = fY - ifY;
+ for(int32_t x=0; x<newx; x++){
+ fX = x * xScale;
+ ifX = (int32_t)fX;
+ ifX1 = min(xmax, ifX+1);
+ dx = fX - ifX;
+ // Interpolate using the four nearest pixels in the source
+ if (head.biClrUsed){
+ rgb1=GetPaletteColor(GetPixelIndex(ifX,ifY));
+ rgb2=GetPaletteColor(GetPixelIndex(ifX1,ifY));
+ rgb3=GetPaletteColor(GetPixelIndex(ifX,ifY1));
+ rgb4=GetPaletteColor(GetPixelIndex(ifX1,ifY1));
+ }
+ else {
+ uint8_t* iDst;
+ iDst = info.pImage + ifY*info.dwEffWidth + ifX*3;
+ rgb1.rgbBlue = *iDst++; rgb1.rgbGreen= *iDst++; rgb1.rgbRed =*iDst;
+ iDst = info.pImage + ifY*info.dwEffWidth + ifX1*3;
+ rgb2.rgbBlue = *iDst++; rgb2.rgbGreen= *iDst++; rgb2.rgbRed =*iDst;
+ iDst = info.pImage + ifY1*info.dwEffWidth + ifX*3;
+ rgb3.rgbBlue = *iDst++; rgb3.rgbGreen= *iDst++; rgb3.rgbRed =*iDst;
+ iDst = info.pImage + ifY1*info.dwEffWidth + ifX1*3;
+ rgb4.rgbBlue = *iDst++; rgb4.rgbGreen= *iDst++; rgb4.rgbRed =*iDst;
+ }
+ // Interplate in x direction:
+ ir1 = rgb1.rgbRed + (rgb3.rgbRed - rgb1.rgbRed) * dy;
+ ig1 = rgb1.rgbGreen + (rgb3.rgbGreen - rgb1.rgbGreen) * dy;
+ ib1 = rgb1.rgbBlue + (rgb3.rgbBlue - rgb1.rgbBlue) * dy;
+ ir2 = rgb2.rgbRed + (rgb4.rgbRed - rgb2.rgbRed) * dy;
+ ig2 = rgb2.rgbGreen + (rgb4.rgbGreen - rgb2.rgbGreen) * dy;
+ ib2 = rgb2.rgbBlue + (rgb4.rgbBlue - rgb2.rgbBlue) * dy;
+ // Interpolate in y:
+ r = (uint8_t)(ir1 + (ir2-ir1) * dx);
+ g = (uint8_t)(ig1 + (ig2-ig1) * dx);
+ b = (uint8_t)(ib1 + (ib2-ib1) * dx);
+ // Set output
+ newImage.SetPixelColor(x,y,RGB(r,g,b));
+ }
+ }
+ } else {
+ //high resolution shrink, thanks to Henrik Stellmann <henrik.stellmann@volleynet.de>
+ const int32_t ACCURACY = 1000;
+ int32_t i,j; // index for faValue
+ int32_t x,y; // coordinates in source image
+ uint8_t* pSource;
+ uint8_t* pDest = newImage.info.pImage;
+ int32_t* naAccu = new int32_t[3 * newx + 3];
+ int32_t* naCarry = new int32_t[3 * newx + 3];
+ int32_t* naTemp;
+ int32_t nWeightX,nWeightY;
+ float fEndX;
+ int32_t nScale = (int32_t)(ACCURACY * xScale * yScale);
+
+ memset(naAccu, 0, sizeof(int32_t) * 3 * newx);
+ memset(naCarry, 0, sizeof(int32_t) * 3 * newx);
+
+ int32_t u, v = 0; // coordinates in dest image
+ float fEndY = yScale - 1.0f;
+ for (y = 0; y < head.biHeight; y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight); //<Anatoly Ivasyuk>
+ if (info.nEscape) break;
+ pSource = info.pImage + y * info.dwEffWidth;
+ u = i = 0;
+ fEndX = xScale - 1.0f;
+ if ((float)y < fEndY) { // complete source row goes into dest row
+ for (x = 0; x < head.biWidth; x++){
+ if ((float)x < fEndX){ // complete source pixel goes into dest pixel
+ for (j = 0; j < 3; j++) naAccu[i + j] += (*pSource++) * ACCURACY;
+ } else { // source pixel is splitted for 2 dest pixels
+ nWeightX = (int32_t)(((float)x - fEndX) * ACCURACY);
+ for (j = 0; j < 3; j++){
+ naAccu[i] += (ACCURACY - nWeightX) * (*pSource);
+ naAccu[3 + i++] += nWeightX * (*pSource++);
+ }
+ fEndX += xScale;
+ u++;
+ }
+ }
+ } else { // source row is splitted for 2 dest rows
+ nWeightY = (int32_t)(((float)y - fEndY) * ACCURACY);
+ for (x = 0; x < head.biWidth; x++){
+ if ((float)x < fEndX){ // complete source pixel goes into 2 pixel
+ for (j = 0; j < 3; j++){
+ naAccu[i + j] += ((ACCURACY - nWeightY) * (*pSource));
+ naCarry[i + j] += nWeightY * (*pSource++);
+ }
+ } else { // source pixel is splitted for 4 dest pixels
+ nWeightX = (int32_t)(((float)x - fEndX) * ACCURACY);
+ for (j = 0; j < 3; j++) {
+ naAccu[i] += ((ACCURACY - nWeightY) * (ACCURACY - nWeightX)) * (*pSource) / ACCURACY;
+ *pDest++ = (uint8_t)(naAccu[i] / nScale);
+ naCarry[i] += (nWeightY * (ACCURACY - nWeightX) * (*pSource)) / ACCURACY;
+ naAccu[i + 3] += ((ACCURACY - nWeightY) * nWeightX * (*pSource)) / ACCURACY;
+ naCarry[i + 3] = (nWeightY * nWeightX * (*pSource)) / ACCURACY;
+ i++;
+ pSource++;
+ }
+ fEndX += xScale;
+ u++;
+ }
+ }
+ if (u < newx){ // possibly not completed due to rounding errors
+ for (j = 0; j < 3; j++) *pDest++ = (uint8_t)(naAccu[i++] / nScale);
+ }
+ naTemp = naCarry;
+ naCarry = naAccu;
+ naAccu = naTemp;
+ memset(naCarry, 0, sizeof(int32_t) * 3); // need only to set first pixel zero
+ pDest = newImage.info.pImage + (++v * newImage.info.dwEffWidth);
+ fEndY += yScale;
+ }
+ }
+ if (v < newy){ // possibly not completed due to rounding errors
+ for (i = 0; i < 3 * newx; i++) *pDest++ = (uint8_t)(naAccu[i] / nScale);
+ }
+ delete [] naAccu;
+ delete [] naCarry;
+ }
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){
+ if (1 == mode){
+ newImage.AlphaCreate();
+ for(int32_t y=0; y<newy; y++){
+ fY = y * yScale;
+ for(int32_t x=0; x<newx; x++){
+ fX = x * xScale;
+ newImage.AlphaSet(x,y,AlphaGet((int32_t)fX,(int32_t)fY));
+ }
+ }
+ } else {
+ CxImage newAlpha;
+ AlphaSplit(&newAlpha);
+ newAlpha.Resample(newx, newy, mode);
+ newImage.AlphaSet(newAlpha);
+ }
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ //select the destination
+ if (iDst) iDst->Transfer(newImage);
+ else Transfer(newImage);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * New simpler resample. Adds new interpolation methods and simplifies code (using GetPixelColorInterpolated
+ * and GetAreaColorInterpolated). It also (unlike old method) interpolates alpha layer.
+ *
+ * \param newx, newy - size of resampled image
+ * \param inMethod - interpolation method to use (see comments at GetPixelColorInterpolated)
+ * If image size is being reduced, averaging is used instead (or simultaneously with) inMethod.
+ * \param ofMethod - what to replace outside pixels by (only significant for bordering pixels of enlarged image)
+ * \param iDst - pointer to destination CxImage or NULL.
+ * \param disableAveraging - force no averaging when shrinking images (Produces aliasing.
+ * You probably just want to leave this off...)
+ *
+ * \author ***bd*** 2.2004
+ */
+bool CxImage::Resample2(
+ int32_t newx, int32_t newy,
+ InterpolationMethod const inMethod,
+ OverflowMethod const ofMethod,
+ CxImage* const iDst,
+ bool const disableAveraging)
+{
+ if (newx<=0 || newy<=0 || !pDib) return false;
+
+ if (head.biWidth==newx && head.biHeight==newy) {
+ //image already correct size (just copy and return)
+ if (iDst) iDst->Copy(*this);
+ return true;
+ }//if
+
+ //calculate scale of new image (less than 1 for enlarge)
+ float xScale, yScale;
+ xScale = (float)head.biWidth / (float)newx;
+ yScale = (float)head.biHeight / (float)newy;
+
+ //create temporary destination image
+ CxImage newImage;
+ newImage.CopyInfo(*this);
+ newImage.Create(newx,newy,head.biBitCount,GetType());
+ newImage.SetPalette(GetPalette());
+ if (!newImage.IsValid()){
+ strcpy(info.szLastError,newImage.GetLastError());
+ return false;
+ }
+
+ //and alpha channel if required
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) newImage.AlphaCreate();
+ uint8_t *pxptra = 0; // destination alpha data
+#endif
+
+ float sX, sY; //source location
+ int32_t dX,dY; //destination pixel (int32_t value)
+ if ((xScale<=1 && yScale<=1) || disableAveraging) {
+ //image is being enlarged (or interpolation on demand)
+ if (!IsIndexed()) {
+ //RGB24 image (optimized version with direct writes)
+ RGBQUAD q; //pixel colour
+ uint8_t *pxptr; //pointer to destination pixel
+ for(dY=0; dY<newy; dY++){
+ info.nProgress = (int32_t)(100*dY/newy);
+ if (info.nEscape) break;
+ sY = (dY + 0.5f) * yScale - 0.5f;
+ pxptr=(uint8_t*)(newImage.BlindGetPixelPointer(0,dY));
+#if CXIMAGE_SUPPORT_ALPHA
+ pxptra=newImage.AlphaGetPointer(0,dY);
+#endif
+ for(dX=0; dX<newx; dX++){
+ sX = (dX + 0.5f) * xScale - 0.5f;
+ q=GetPixelColorInterpolated(sX,sY,inMethod,ofMethod,0);
+ *pxptr++=q.rgbBlue;
+ *pxptr++=q.rgbGreen;
+ *pxptr++=q.rgbRed;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pxptra) *pxptra++=q.rgbReserved;
+#endif
+ }//for dX
+ }//for dY
+ } else {
+ //enlarge paletted image. Slower method.
+ for(dY=0; dY<newy; dY++){
+ info.nProgress = (int32_t)(100*dY/newy);
+ if (info.nEscape) break;
+ sY = (dY + 0.5f) * yScale - 0.5f;
+ for(dX=0; dX<newx; dX++){
+ sX = (dX + 0.5f) * xScale - 0.5f;
+ newImage.SetPixelColor(dX,dY,GetPixelColorInterpolated(sX,sY,inMethod,ofMethod,0),true);
+ }//for x
+ }//for y
+ }//if
+ } else {
+ //image size is being reduced (averaging enabled)
+ for(dY=0; dY<newy; dY++){
+ info.nProgress = (int32_t)(100*dY/newy); if (info.nEscape) break;
+ sY = (dY+0.5f) * yScale - 0.5f;
+ for(dX=0; dX<newx; dX++){
+ sX = (dX+0.5f) * xScale - 0.5f;
+ newImage.SetPixelColor(dX,dY,GetAreaColorInterpolated(sX, sY, xScale, yScale, inMethod, ofMethod,0),true);
+ }//for x
+ }//for y
+ }//if
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid() && pxptra == 0){
+ for(int32_t y=0; y<newy; y++){
+ dY = (int32_t)(y * yScale);
+ for(int32_t x=0; x<newx; x++){
+ dX = (int32_t)(x * xScale);
+ newImage.AlphaSet(x,y,AlphaGet(dX,dY));
+ }
+ }
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ //copy new image to the destination
+ if (iDst)
+ iDst->Transfer(newImage);
+ else
+ Transfer(newImage);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Reduces the number of bits per pixel to nbit (1, 4 or 8).
+ * ppal points to a valid palette for the final image; if not supplied the function will use a standard palette.
+ * ppal is not necessary for reduction to 1 bpp.
+ */
+bool CxImage::DecreaseBpp(uint32_t nbit, bool errordiffusion, RGBQUAD* ppal, uint32_t clrimportant)
+{
+ if (!pDib) return false;
+ if (head.biBitCount < nbit){
+ strcpy(info.szLastError,"DecreaseBpp: target BPP greater than source BPP");
+ return false;
+ }
+ if (head.biBitCount == nbit){
+ if (clrimportant==0) return true;
+ if (head.biClrImportant && (head.biClrImportant<clrimportant)) return true;
+ }
+
+ int32_t er,eg,eb;
+ RGBQUAD c,ce;
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(head.biWidth,head.biHeight,(uint16_t)nbit,info.dwType);
+ if (clrimportant) tmp.SetClrImportant(clrimportant);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+#if CXIMAGE_SUPPORT_SELECTION
+ tmp.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaCopy(*this);
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ if (ppal) {
+ if (clrimportant) {
+ tmp.SetPalette(ppal,clrimportant);
+ } else {
+ tmp.SetPalette(ppal,1<<tmp.head.biBitCount);
+ }
+ } else {
+ tmp.SetStdPalette();
+ }
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ if (info.nEscape) break;
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ for (int32_t x=0;x<head.biWidth;x++){
+ if (!errordiffusion){
+ tmp.BlindSetPixelColor(x,y,BlindGetPixelColor(x,y));
+ } else {
+ c = BlindGetPixelColor(x,y);
+ tmp.BlindSetPixelColor(x,y,c);
+
+ ce = tmp.BlindGetPixelColor(x,y);
+ er=(int32_t)c.rgbRed - (int32_t)ce.rgbRed;
+ eg=(int32_t)c.rgbGreen - (int32_t)ce.rgbGreen;
+ eb=(int32_t)c.rgbBlue - (int32_t)ce.rgbBlue;
+
+ c = GetPixelColor(x+1,y);
+ c.rgbRed = (uint8_t)min(255L,max(0L,(int32_t)c.rgbRed + ((er*7)/16)));
+ c.rgbGreen = (uint8_t)min(255L,max(0L,(int32_t)c.rgbGreen + ((eg*7)/16)));
+ c.rgbBlue = (uint8_t)min(255L,max(0L,(int32_t)c.rgbBlue + ((eb*7)/16)));
+ SetPixelColor(x+1,y,c);
+ int32_t coeff=1;
+ for(int32_t i=-1; i<2; i++){
+ switch(i){
+ case -1:
+ coeff=2; break;
+ case 0:
+ coeff=4; break;
+ case 1:
+ coeff=1; break;
+ }
+ c = GetPixelColor(x+i,y+1);
+ c.rgbRed = (uint8_t)min(255L,max(0L,(int32_t)c.rgbRed + ((er * coeff)/16)));
+ c.rgbGreen = (uint8_t)min(255L,max(0L,(int32_t)c.rgbGreen + ((eg * coeff)/16)));
+ c.rgbBlue = (uint8_t)min(255L,max(0L,(int32_t)c.rgbBlue + ((eb * coeff)/16)));
+ SetPixelColor(x+i,y+1,c);
+ }
+ }
+ }
+ }
+
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Converts the image to B&W using the desired method :
+ * - 0 = Floyd-Steinberg
+ * - 1 = Ordered-Dithering (4x4)
+ * - 2 = Burkes
+ * - 3 = Stucki
+ * - 4 = Jarvis-Judice-Ninke
+ * - 5 = Sierra
+ * - 6 = Stevenson-Arce
+ * - 7 = Bayer (4x4 ordered dithering)
+ * - 8 = Bayer (8x8 ordered dithering)
+ * - 9 = Bayer (16x16 ordered dithering)
+ */
+bool CxImage::Dither(int32_t method)
+{
+ if (!pDib) return false;
+ if (head.biBitCount == 1) return true;
+
+ GrayScale();
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(head.biWidth, head.biHeight, 1, info.dwType);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+#if CXIMAGE_SUPPORT_SELECTION
+ tmp.SelectionCopy(*this);
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaCopy(*this);
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ switch (method){
+ case 1:
+ {
+ // Multi-Level Ordered-Dithering by Kenny Hoff (Oct. 12, 1995)
+ #define dth_NumRows 4
+ #define dth_NumCols 4
+ #define dth_NumIntensityLevels 2
+ #define dth_NumRowsLessOne (dth_NumRows-1)
+ #define dth_NumColsLessOne (dth_NumCols-1)
+ #define dth_RowsXCols (dth_NumRows*dth_NumCols)
+ #define dth_MaxIntensityVal 255
+ #define dth_MaxDitherIntensityVal (dth_NumRows*dth_NumCols*(dth_NumIntensityLevels-1))
+
+ int32_t DitherMatrix[dth_NumRows][dth_NumCols] = {{0,8,2,10}, {12,4,14,6}, {3,11,1,9}, {15,7,13,5} };
+
+ uint8_t Intensity[dth_NumIntensityLevels] = { 0,1 }; // 2 LEVELS B/W
+ //uint8_t Intensity[NumIntensityLevels] = { 0,255 }; // 2 LEVELS
+ //uint8_t Intensity[NumIntensityLevels] = { 0,127,255 }; // 3 LEVELS
+ //uint8_t Intensity[NumIntensityLevels] = { 0,85,170,255 }; // 4 LEVELS
+ //uint8_t Intensity[NumIntensityLevels] = { 0,63,127,191,255 }; // 5 LEVELS
+ //uint8_t Intensity[NumIntensityLevels] = { 0,51,102,153,204,255 }; // 6 LEVELS
+ //uint8_t Intensity[NumIntensityLevels] = { 0,42,85,127,170,213,255 }; // 7 LEVELS
+ //uint8_t Intensity[NumIntensityLevels] = { 0,36,73,109,145,182,219,255 }; // 8 LEVELS
+ int32_t DitherIntensity, DitherMatrixIntensity, Offset, DeviceIntensity;
+ uint8_t DitherValue;
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+
+ DeviceIntensity = BlindGetPixelIndex(x,y);
+ DitherIntensity = DeviceIntensity*dth_MaxDitherIntensityVal/dth_MaxIntensityVal;
+ DitherMatrixIntensity = DitherIntensity % dth_RowsXCols;
+ Offset = DitherIntensity / dth_RowsXCols;
+ if (DitherMatrix[y&dth_NumRowsLessOne][x&dth_NumColsLessOne] < DitherMatrixIntensity)
+ DitherValue = Intensity[1+Offset];
+ else
+ DitherValue = Intensity[0+Offset];
+
+ tmp.BlindSetPixelIndex(x,y,DitherValue);
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ //Burkes error diffusion (Thanks to Franco Gerevini)
+ int32_t TotalCoeffSum = 32;
+ int32_t error, nlevel, coeff=1;
+ uint8_t level;
+
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ info.nProgress = (int32_t)(100 * y / head.biHeight);
+ if (info.nEscape)
+ break;
+ for (int32_t x = 0; x < head.biWidth; x++) {
+ level = BlindGetPixelIndex(x, y);
+ if (level > 128) {
+ tmp.SetPixelIndex(x, y, 1);
+ error = level - 255;
+ } else {
+ tmp.SetPixelIndex(x, y, 0);
+ error = level;
+ }
+
+ nlevel = GetPixelIndex(x + 1, y) + (error * 8) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 1, y, level);
+ nlevel = GetPixelIndex(x + 2, y) + (error * 4) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 2, y, level);
+ int32_t i;
+ for (i = -2; i < 3; i++) {
+ switch (i) {
+ case -2:
+ coeff = 2;
+ break;
+ case -1:
+ coeff = 4;
+ break;
+ case 0:
+ coeff = 8;
+ break;
+ case 1:
+ coeff = 4;
+ break;
+ case 2:
+ coeff = 2;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 1, level);
+ }
+ }
+ }
+ break;
+ }
+ case 3:
+ {
+ //Stucki error diffusion (Thanks to Franco Gerevini)
+ int32_t TotalCoeffSum = 42;
+ int32_t error, nlevel, coeff=1;
+ uint8_t level;
+
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ info.nProgress = (int32_t)(100 * y / head.biHeight);
+ if (info.nEscape)
+ break;
+ for (int32_t x = 0; x < head.biWidth; x++) {
+ level = BlindGetPixelIndex(x, y);
+ if (level > 128) {
+ tmp.SetPixelIndex(x, y, 1);
+ error = level - 255;
+ } else {
+ tmp.SetPixelIndex(x, y, 0);
+ error = level;
+ }
+
+ nlevel = GetPixelIndex(x + 1, y) + (error * 8) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 1, y, level);
+ nlevel = GetPixelIndex(x + 2, y) + (error * 4) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 2, y, level);
+ int32_t i;
+ for (i = -2; i < 3; i++) {
+ switch (i) {
+ case -2:
+ coeff = 2;
+ break;
+ case -1:
+ coeff = 4;
+ break;
+ case 0:
+ coeff = 8;
+ break;
+ case 1:
+ coeff = 4;
+ break;
+ case 2:
+ coeff = 2;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 1, level);
+ }
+ for (i = -2; i < 3; i++) {
+ switch (i) {
+ case -2:
+ coeff = 1;
+ break;
+ case -1:
+ coeff = 2;
+ break;
+ case 0:
+ coeff = 4;
+ break;
+ case 1:
+ coeff = 2;
+ break;
+ case 2:
+ coeff = 1;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 2) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 2, level);
+ }
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ //Jarvis, Judice and Ninke error diffusion (Thanks to Franco Gerevini)
+ int32_t TotalCoeffSum = 48;
+ int32_t error, nlevel, coeff=1;
+ uint8_t level;
+
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ info.nProgress = (int32_t)(100 * y / head.biHeight);
+ if (info.nEscape)
+ break;
+ for (int32_t x = 0; x < head.biWidth; x++) {
+ level = BlindGetPixelIndex(x, y);
+ if (level > 128) {
+ tmp.SetPixelIndex(x, y, 1);
+ error = level - 255;
+ } else {
+ tmp.SetPixelIndex(x, y, 0);
+ error = level;
+ }
+
+ nlevel = GetPixelIndex(x + 1, y) + (error * 7) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 1, y, level);
+ nlevel = GetPixelIndex(x + 2, y) + (error * 5) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 2, y, level);
+ int32_t i;
+ for (i = -2; i < 3; i++) {
+ switch (i) {
+ case -2:
+ coeff = 3;
+ break;
+ case -1:
+ coeff = 5;
+ break;
+ case 0:
+ coeff = 7;
+ break;
+ case 1:
+ coeff = 5;
+ break;
+ case 2:
+ coeff = 3;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 1, level);
+ }
+ for (i = -2; i < 3; i++) {
+ switch (i) {
+ case -2:
+ coeff = 1;
+ break;
+ case -1:
+ coeff = 3;
+ break;
+ case 0:
+ coeff = 5;
+ break;
+ case 1:
+ coeff = 3;
+ break;
+ case 2:
+ coeff = 1;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 2) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 2, level);
+ }
+ }
+ }
+ break;
+ }
+ case 5:
+ {
+ //Sierra error diffusion (Thanks to Franco Gerevini)
+ int32_t TotalCoeffSum = 32;
+ int32_t error, nlevel, coeff=1;
+ uint8_t level;
+
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ info.nProgress = (int32_t)(100 * y / head.biHeight);
+ if (info.nEscape)
+ break;
+ for (int32_t x = 0; x < head.biWidth; x++) {
+ level = BlindGetPixelIndex(x, y);
+ if (level > 128) {
+ tmp.SetPixelIndex(x, y, 1);
+ error = level - 255;
+ } else {
+ tmp.SetPixelIndex(x, y, 0);
+ error = level;
+ }
+
+ nlevel = GetPixelIndex(x + 1, y) + (error * 5) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 1, y, level);
+ nlevel = GetPixelIndex(x + 2, y) + (error * 3) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + 2, y, level);
+ int32_t i;
+ for (i = -2; i < 3; i++) {
+ switch (i) {
+ case -2:
+ coeff = 2;
+ break;
+ case -1:
+ coeff = 4;
+ break;
+ case 0:
+ coeff = 5;
+ break;
+ case 1:
+ coeff = 4;
+ break;
+ case 2:
+ coeff = 2;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 1, level);
+ }
+ for (i = -1; i < 2; i++) {
+ switch (i) {
+ case -1:
+ coeff = 2;
+ break;
+ case 0:
+ coeff = 3;
+ break;
+ case 1:
+ coeff = 2;
+ break;
+ }
+ nlevel = GetPixelIndex(x + i, y + 2) + (error * coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(x + i, y + 2, level);
+ }
+ }
+ }
+ break;
+ }
+ case 6:
+ {
+ //Stevenson and Arce error diffusion (Thanks to Franco Gerevini)
+ int32_t TotalCoeffSum = 200;
+ int32_t error, nlevel;
+ uint8_t level;
+
+ for (int32_t y = 0; y < head.biHeight; y++) {
+ info.nProgress = (int32_t)(100 * y / head.biHeight);
+ if (info.nEscape)
+ break;
+ for (int32_t x = 0; x < head.biWidth; x++) {
+ level = BlindGetPixelIndex(x, y);
+ if (level > 128) {
+ tmp.SetPixelIndex(x, y, 1);
+ error = level - 255;
+ } else {
+ tmp.SetPixelIndex(x, y, 0);
+ error = level;
+ }
+
+ int32_t tmp_index_x = x + 2;
+ int32_t tmp_index_y = y;
+ int32_t tmp_coeff = 32;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x - 3;
+ tmp_index_y = y + 1;
+ tmp_coeff = 12;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x - 1;
+ tmp_coeff = 26;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x + 1;
+ tmp_coeff = 30;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x + 3;
+ tmp_coeff = 16;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x - 2;
+ tmp_index_y = y + 2;
+ tmp_coeff = 12;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x;
+ tmp_coeff = 26;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x + 2;
+ tmp_coeff = 12;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x - 3;
+ tmp_index_y = y + 3;
+ tmp_coeff = 5;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x - 1;
+ tmp_coeff = 12;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x + 1;
+ tmp_coeff = 12;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+
+ tmp_index_x = x + 3;
+ tmp_coeff = 5;
+ nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
+ level = (uint8_t)min(255, max(0, (int32_t)nlevel));
+ SetPixelIndex(tmp_index_x, tmp_index_y, level);
+ }
+ }
+ break;
+ }
+ case 7:
+ {
+ // Bayer ordered dither
+ int32_t order = 4;
+ //create Bayer matrix
+ if (order>4) order = 4;
+ int32_t size = (1 << (2*order));
+ uint8_t* Bmatrix = (uint8_t*) malloc(size * sizeof(uint8_t));
+ for(int32_t i = 0; i < size; i++) {
+ int32_t n = order;
+ int32_t x = i / n;
+ int32_t y = i % n;
+ int32_t dither = 0;
+ while (n-- > 0){
+ dither = (((dither<<1)|((x&1) ^ (y&1)))<<1) | (y&1);
+ x >>= 1;
+ y >>= 1;
+ }
+ Bmatrix[i] = (uint8_t)(dither);
+ }
+
+ int32_t scale = max(0,(8-2*order));
+ int32_t level;
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ level = BlindGetPixelIndex(x,y) >> scale;
+ if(level > Bmatrix[ (x % order) + order * (y % order) ]){
+ tmp.SetPixelIndex(x,y,1);
+ } else {
+ tmp.SetPixelIndex(x,y,0);
+ }
+ }
+ }
+
+ free(Bmatrix);
+
+ break;
+ }
+ case 8:
+ {
+ // 8x8 Bayer ordered dither
+ int32_t const pattern8x8[8][8] = {
+ { 0, 32, 8, 40, 2, 34, 10, 42}, /* 8x8 Bayer ordered dithering */
+ {48, 16, 56, 24, 50, 18, 58, 26}, /* pattern. Each input pixel */
+ {12, 44, 4, 36, 14, 46, 6, 38}, /* is scaled to the 0..63 range */
+ {60, 28, 52, 20, 62, 30, 54, 22}, /* before looking in this table */
+ { 3, 35, 11, 43, 1, 33, 9, 41}, /* to determine the action. */
+ {51, 19, 59, 27, 49, 17, 57, 25},
+ {15, 47, 7, 39, 13, 45, 5, 37},
+ {63, 31, 55, 23, 61, 29, 53, 21} };
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ int32_t level = BlindGetPixelIndex(x,y) >> 2;
+ if(level && level >= pattern8x8[x & 7][y & 7]){
+ tmp.SetPixelIndex(x,y,1);
+ } else {
+ tmp.SetPixelIndex(x,y,0);
+ }
+ }
+ }
+ break;
+ }
+ case 9:
+ {
+ // 16x16 Bayer ordered dither
+ int32_t const pattern16x16[16][16] = {
+ { 1,235, 59,219, 15,231, 55,215, 2,232, 56,216, 12,228, 52,212},
+ { 129, 65,187,123,143, 79,183,119,130, 66,184,120,140, 76,180,116},
+ { 33,193, 17,251, 47,207, 31,247, 34,194, 18,248, 44,204, 28,244},
+ { 161, 97,145, 81,175,111,159, 95,162, 98,146, 82,172,108,156, 92},
+ { 9,225, 49,209, 5,239, 63,223, 10,226, 50,210, 6,236, 60,220},
+ { 137, 73,177,113,133, 69,191,127,138, 74,178,114,134, 70,188,124},
+ { 41,201, 25,241, 37,197, 21,255, 42,202, 26,242, 38,198, 22,252},
+ { 169,105,153, 89,165,101,149, 85,170,106,154, 90,166,102,150, 86},
+ { 3,233, 57,217, 13,229, 53,213, 0,234, 58,218, 14,230, 54,214},
+ { 131, 67,185,121,141, 77,181,117,128, 64,186,122,142, 78,182,118},
+ { 35,195, 19,249, 45,205, 29,245, 32,192, 16,250, 46,206, 30,246},
+ { 163, 99,147, 83,173,109,157, 93,160, 96,144, 80,174,110,158, 94},
+ { 11,227, 51,211, 7,237, 61,221, 8,224, 48,208, 4,238, 62,222},
+ { 139, 75,179,115,135, 71,189,125,136, 72,176,112,132, 68,190,126},
+ { 43,203, 27,243, 39,199, 23,253, 40,200, 24,240, 36,196, 20,254},
+ { 171,107,155, 91,167,103,151, 87,168,104,152, 88,164,100,148, 84}
+ };
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+ if (BlindGetPixelIndex(x,y) > pattern16x16[x & 15][y & 15]){
+ tmp.SetPixelIndex(x,y,1);
+ } else {
+ tmp.SetPixelIndex(x,y,0);
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ // Floyd-Steinberg error diffusion (Thanks to Steve McMahon)
+ int32_t error,nlevel,coeff=1;
+ uint8_t level;
+
+ for (int32_t y=0;y<head.biHeight;y++){
+ info.nProgress = (int32_t)(100*y/head.biHeight);
+ if (info.nEscape) break;
+ for (int32_t x=0;x<head.biWidth;x++){
+
+ level = BlindGetPixelIndex(x,y);
+ if (level > 128){
+ tmp.SetPixelIndex(x,y,1);
+ error = level-255;
+ } else {
+ tmp.SetPixelIndex(x,y,0);
+ error = level;
+ }
+
+ nlevel = GetPixelIndex(x+1,y) + (error * 7)/16;
+ level = (uint8_t)min(255,max(0,(int32_t)nlevel));
+ SetPixelIndex(x+1,y,level);
+ for(int32_t i=-1; i<2; i++){
+ switch(i){
+ case -1:
+ coeff=3; break;
+ case 0:
+ coeff=5; break;
+ case 1:
+ coeff=1; break;
+ }
+ nlevel = GetPixelIndex(x+i,y+1) + (error * coeff)/16;
+ level = (uint8_t)min(255,max(0,(int32_t)nlevel));
+ SetPixelIndex(x+i,y+1,level);
+ }
+ }
+ }
+ }
+ }
+
+ tmp.SetPaletteColor(0,0,0,0);
+ tmp.SetPaletteColor(1,255,255,255);
+ Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * CropRotatedRectangle
+ * \param topx,topy : topmost and leftmost point of the rectangle
+ (topmost, and if there are 2 topmost points, the left one)
+ * \param width : size of the right hand side of rect, from (topx,topy) roundwalking clockwise
+ * \param height : size of the left hand side of rect, from (topx,topy) roundwalking clockwise
+ * \param angle : angle of the right hand side of rect, from (topx,topy)
+ * \param iDst : pointer to destination image (if 0, this image is modified)
+ * \author [VATI]
+ */
+bool CxImage::CropRotatedRectangle( int32_t topx, int32_t topy, int32_t width, int32_t height, float angle, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+
+ int32_t startx,starty,endx,endy;
+ double cos_angle = cos(angle/*/57.295779513082320877*/);
+ double sin_angle = sin(angle/*/57.295779513082320877*/);
+
+ // if there is nothing special, call the original Crop():
+ if ( fabs(angle)<0.0002 )
+ return Crop( topx, topy, topx+width, topy+height, iDst);
+
+ startx = min(topx, topx - (int32_t)(sin_angle*(double)height));
+ endx = topx + (int32_t)(cos_angle*(double)width);
+ endy = topy + (int32_t)(cos_angle*(double)height + sin_angle*(double)width);
+ // check: corners of the rectangle must be inside
+ if ( IsInside( startx, topy )==false ||
+ IsInside( endx, endy ) == false )
+ return false;
+
+ // first crop to bounding rectangle
+ CxImage tmp(*this, true, false, true);
+ // tmp.Copy(*this, true, false, true);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+ if (!tmp.Crop( startx, topy, endx, endy)){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ // the midpoint of the image now became the same as the midpoint of the rectangle
+ // rotate new image with minus angle amount
+ if ( false == tmp.Rotate( (float)(-angle*57.295779513082320877) ) ) // Rotate expects angle in degrees
+ return false;
+
+ // crop rotated image to the original selection rectangle
+ endx = (tmp.head.biWidth+width)/2;
+ startx = (tmp.head.biWidth-width)/2;
+ starty = (tmp.head.biHeight+height)/2;
+ endy = (tmp.head.biHeight-height)/2;
+ if ( false == tmp.Crop( startx, starty, endx, endy ) )
+ return false;
+
+ if (iDst) iDst->Transfer(tmp);
+ else Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Crop(const RECT& rect, CxImage* iDst)
+{
+ return Crop(rect.left, rect.top, rect.right, rect.bottom, iDst);
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Crop(int32_t left, int32_t top, int32_t right, int32_t bottom, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ int32_t startx = max(0L,min(left,head.biWidth));
+ int32_t endx = max(0L,min(right,head.biWidth));
+ int32_t starty = head.biHeight - max(0L,min(top,head.biHeight));
+ int32_t endy = head.biHeight - max(0L,min(bottom,head.biHeight));
+
+ if (startx==endx || starty==endy) return false;
+
+ if (startx>endx) {int32_t tmp=startx; startx=endx; endx=tmp;}
+ if (starty>endy) {int32_t tmp=starty; starty=endy; endy=tmp;}
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ tmp.Create(endx-startx,endy-starty,head.biBitCount,info.dwType);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ tmp.SetPalette(GetPalette(),head.biClrUsed);
+ tmp.info.nBkgndIndex = info.nBkgndIndex;
+ tmp.info.nBkgndColor = info.nBkgndColor;
+
+ switch (head.biBitCount) {
+ case 1:
+ case 4:
+ {
+ for(int32_t y=starty, yd=0; y<endy; y++, yd++){
+ info.nProgress = (int32_t)(100*(y-starty)/(endy-starty)); //<Anatoly Ivasyuk>
+ for(int32_t x=startx, xd=0; x<endx; x++, xd++){
+ tmp.SetPixelIndex(xd,yd,GetPixelIndex(x,y));
+ }
+ }
+ break;
+ }
+ case 8:
+ case 24:
+ {
+ int32_t linelen = tmp.head.biWidth * tmp.head.biBitCount >> 3;
+ uint8_t* pDest = tmp.info.pImage;
+ uint8_t* pSrc = info.pImage + starty * info.dwEffWidth + (startx*head.biBitCount >> 3);
+ for(int32_t y=starty; y<endy; y++){
+ info.nProgress = (int32_t)(100*(y-starty)/(endy-starty)); //<Anatoly Ivasyuk>
+ memcpy(pDest,pSrc,linelen);
+ pDest+=tmp.info.dwEffWidth;
+ pSrc+=info.dwEffWidth;
+ }
+ }
+ }
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){ //<oboolo>
+ tmp.AlphaCreate();
+ if (!tmp.AlphaIsValid()) return false;
+ uint8_t* pDest = tmp.pAlpha;
+ uint8_t* pSrc = pAlpha + startx + starty*head.biWidth;
+ for (int32_t y=starty; y<endy; y++){
+ memcpy(pDest,pSrc,endx-startx);
+ pDest+=tmp.head.biWidth;
+ pSrc+=head.biWidth;
+ }
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ //select the destination
+ if (iDst) iDst->Transfer(tmp);
+ else Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * \param xgain, ygain : can be from 0 to 1.
+ * \param xpivot, ypivot : is the center of the transformation.
+ * \param bEnableInterpolation : if true, enables bilinear interpolation.
+ * \return true if everything is ok
+ */
+bool CxImage::Skew(float xgain, float ygain, int32_t xpivot, int32_t ypivot, bool bEnableInterpolation)
+{
+ if (!pDib) return false;
+ float nx,ny;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ nx = x + (xgain*(y - ypivot));
+ ny = y + (ygain*(x - xpivot));
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bEnableInterpolation){
+ tmp.SetPixelColor(x,y,GetPixelColorInterpolated(nx, ny, CxImage::IM_BILINEAR, CxImage::OM_BACKGROUND),true);
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ if (head.biClrUsed==0){
+ tmp.SetPixelColor(x,y,GetPixelColor((int32_t)nx,(int32_t)ny));
+ } else {
+ tmp.SetPixelIndex(x,y,GetPixelIndex((int32_t)nx,(int32_t)ny));
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaSet(x,y,AlphaGet((int32_t)nx,(int32_t)ny));
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Expands the borders.
+ * \param left, top, right, bottom = additional dimensions, should be greater than 0.
+ * \param canvascolor = border color. canvascolor.rgbReserved will set the alpha channel (if any) in the border.
+ * \param iDst = pointer to destination image (if it's 0, this image is modified)
+ * \return true if everything is ok
+ * \author [Colin Urquhart]; changes [DP]
+ */
+bool CxImage::Expand(int32_t left, int32_t top, int32_t right, int32_t bottom, RGBQUAD canvascolor, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ if ((left < 0) || (right < 0) || (bottom < 0) || (top < 0)) return false;
+
+ int32_t newWidth = head.biWidth + left + right;
+ int32_t newHeight = head.biHeight + top + bottom;
+
+ right = left + head.biWidth - 1;
+ top = bottom + head.biHeight - 1;
+
+ CxImage tmp;
+ tmp.CopyInfo(*this);
+ if (!tmp.Create(newWidth, newHeight, head.biBitCount, info.dwType)){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ tmp.SetPalette(GetPalette(),head.biClrUsed);
+
+ switch (head.biBitCount) {
+ case 1:
+ case 4:
+ {
+ uint8_t pixel = tmp.GetNearestIndex(canvascolor);
+ for(int32_t y=0; y < newHeight; y++){
+ info.nProgress = (int32_t)(100*y/newHeight);
+ for(int32_t x=0; x < newWidth; x++){
+ if ((y < bottom) || (y > top) || (x < left) || (x > right)) {
+ tmp.SetPixelIndex(x,y, pixel);
+ } else {
+ tmp.SetPixelIndex(x,y,GetPixelIndex(x-left,y-bottom));
+ }
+ }
+ }
+ break;
+ }
+ case 8:
+ case 24:
+ {
+ if (head.biBitCount == 8) {
+ uint8_t pixel = tmp.GetNearestIndex( canvascolor);
+ memset(tmp.info.pImage, pixel, + (tmp.info.dwEffWidth * newHeight));
+ } else {
+ for (int32_t y = 0; y < newHeight; ++y) {
+ uint8_t *pDest = tmp.info.pImage + (y * tmp.info.dwEffWidth);
+ for (int32_t x = 0; x < newWidth; ++x) {
+ *pDest++ = canvascolor.rgbBlue;
+ *pDest++ = canvascolor.rgbGreen;
+ *pDest++ = canvascolor.rgbRed;
+ }
+ }
+ }
+
+ uint8_t* pDest = tmp.info.pImage + (tmp.info.dwEffWidth * bottom) + (left*(head.biBitCount >> 3));
+ uint8_t* pSrc = info.pImage;
+ for(int32_t y=bottom; y <= top; y++){
+ info.nProgress = (int32_t)(100*y/(1 + top - bottom));
+ memcpy(pDest,pSrc,(head.biBitCount >> 3) * (right - left + 1));
+ pDest+=tmp.info.dwEffWidth;
+ pSrc+=info.dwEffWidth;
+ }
+ }
+ }
+
+#if CXIMAGE_SUPPORT_SELECTION
+ if (SelectionIsValid()){
+ if (!tmp.SelectionCreate())
+ return false;
+ uint8_t* pSrc = SelectionGetPointer();
+ uint8_t* pDst = tmp.SelectionGetPointer(left,bottom);
+ for(int32_t y=bottom; y <= top; y++){
+ memcpy(pDst,pSrc, (right - left + 1));
+ pSrc+=head.biWidth;
+ pDst+=tmp.head.biWidth;
+ }
+ tmp.info.rSelectionBox.left = info.rSelectionBox.left + left;
+ tmp.info.rSelectionBox.right = info.rSelectionBox.right + left;
+ tmp.info.rSelectionBox.top = info.rSelectionBox.top + bottom;
+ tmp.info.rSelectionBox.bottom = info.rSelectionBox.bottom + bottom;
+ }
+#endif //CXIMAGE_SUPPORT_SELECTION
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()){
+ if (!tmp.AlphaCreate())
+ return false;
+ tmp.AlphaSet(canvascolor.rgbReserved);
+ uint8_t* pSrc = AlphaGetPointer();
+ uint8_t* pDst = tmp.AlphaGetPointer(left,bottom);
+ for(int32_t y=bottom; y <= top; y++){
+ memcpy(pDst,pSrc, (right - left + 1));
+ pSrc+=head.biWidth;
+ pDst+=tmp.head.biWidth;
+ }
+ }
+#endif //CXIMAGE_SUPPORT_ALPHA
+
+ //select the destination
+ if (iDst) iDst->Transfer(tmp);
+ else Transfer(tmp);
+
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImage::Expand(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst)
+{
+ //thanks to <Colin Urquhart>
+
+ if (!pDib) return false;
+
+ if ((newx < head.biWidth) || (newy < head.biHeight)) return false;
+
+ int32_t nAddLeft = (newx - head.biWidth) / 2;
+ int32_t nAddTop = (newy - head.biHeight) / 2;
+
+ return Expand(nAddLeft, nAddTop, newx - (head.biWidth + nAddLeft), newy - (head.biHeight + nAddTop), canvascolor, iDst);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Resamples the image with the correct aspect ratio, and fills the borders.
+ * \param newx, newy = thumbnail size.
+ * \param canvascolor = border color.
+ * \param iDst = pointer to destination image (if it's 0, this image is modified).
+ * \return true if everything is ok.
+ * \author [Colin Urquhart]
+ */
+bool CxImage::Thumbnail(int32_t newx, int32_t newy, RGBQUAD canvascolor, CxImage* iDst)
+{
+ if (!pDib) return false;
+
+ if ((newx <= 0) || (newy <= 0)) return false;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ // determine whether we need to shrink the image
+ if ((head.biWidth > newx) || (head.biHeight > newy)) {
+ float fScale;
+ float fAspect = (float) newx / (float) newy;
+ if (fAspect * head.biHeight > head.biWidth) {
+ fScale = (float) newy / head.biHeight;
+ } else {
+ fScale = (float) newx / head.biWidth;
+ }
+ tmp.Resample((int32_t) (fScale * head.biWidth), (int32_t) (fScale * head.biHeight), 0);
+ }
+
+ // expand the frame
+ tmp.Expand(newx, newy, canvascolor);
+
+ //select the destination
+ if (iDst) iDst->Transfer(tmp);
+ else Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Perform circle_based transformations.
+ * \param type - for different transformations
+ * - 0 for normal (proturberant) FishEye
+ * - 1 for reverse (concave) FishEye
+ * - 2 for Swirle
+ * - 3 for Cilinder mirror
+ * - 4 for bathroom
+ *
+ * \param rmax - effect radius. If 0, the whole image is processed
+ * \param Koeff - only for swirle
+ * \author Arkadiy Olovyannikov ark(at)msun(dot)ru
+ */
+bool CxImage::CircleTransform(int32_t type,int32_t rmax,float Koeff)
+{
+ if (!pDib) return false;
+
+ int32_t nx,ny;
+ double angle,radius,rnew;
+
+ CxImage tmp(*this);
+ if (!tmp.IsValid()){
+ strcpy(info.szLastError,tmp.GetLastError());
+ return false;
+ }
+
+ int32_t xmin,xmax,ymin,ymax,xmid,ymid;
+ if (pSelection){
+ xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
+ ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
+ } else {
+ xmin = ymin = 0;
+ xmax = head.biWidth; ymax=head.biHeight;
+ }
+
+ xmid = (int32_t) (tmp.GetWidth()/2);
+ ymid = (int32_t) (tmp.GetHeight()/2);
+
+ if (!rmax) rmax=(int32_t)sqrt((float)((xmid-xmin)*(xmid-xmin)+(ymid-ymin)*(ymid-ymin)));
+ if (Koeff==0.0f) Koeff=1.0f;
+
+ for(int32_t y=ymin; y<ymax; y++){
+ info.nProgress = (int32_t)(100*(y-ymin)/(ymax-ymin));
+ if (info.nEscape) break;
+ for(int32_t x=xmin; x<xmax; x++){
+#if CXIMAGE_SUPPORT_SELECTION
+ if (BlindSelectionIsInside(x,y))
+#endif //CXIMAGE_SUPPORT_SELECTION
+ {
+ nx=xmid-x;
+ ny=ymid-y;
+ radius=sqrt((float)(nx*nx+ny*ny));
+ if (radius<rmax) {
+ angle=atan2((double)ny,(double)nx);
+ if (type==0) rnew=radius*radius/rmax;
+ else if (type==1) rnew=sqrt(radius*rmax);
+ else if (type==2) {rnew=radius;angle += radius / Koeff;}
+ else rnew = 1; // potentially uninitialized
+ if (type<3){
+ nx = xmid + (int32_t)(rnew * cos(angle));
+ ny = ymid - (int32_t)(rnew * sin(angle));
+ }
+ else if (type==3){
+ nx = (int32_t)fabs((angle*xmax/6.2831852));
+ ny = (int32_t)fabs((radius*ymax/rmax));
+ }
+ else {
+ nx=x+(x%32)-16;
+ ny=y;
+ }
+// nx=max(xmin,min(nx,xmax));
+// ny=max(ymin,min(ny,ymax));
+ }
+ else { nx=-1;ny=-1;}
+ if (head.biClrUsed==0){
+ tmp.SetPixelColor(x,y,GetPixelColor(nx,ny));
+ } else {
+ tmp.SetPixelIndex(x,y,GetPixelIndex(nx,ny));
+ }
+#if CXIMAGE_SUPPORT_ALPHA
+ tmp.AlphaSet(x,y,AlphaGet(nx,ny));
+#endif //CXIMAGE_SUPPORT_ALPHA
+ }
+ }
+ }
+ Transfer(tmp);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Faster way to almost properly shrink image. Algorithm produces results comparable with "high resoultion shrink"
+ * when resulting image is much smaller (that would be 3 times or more) than original. When
+ * resulting image is only slightly smaller, results are closer to nearest pixel.
+ * This algorithm works by averaging, but it does not calculate fractions of pixels. It adds whole
+ * source pixels to the best destionation. It is not geometrically "correct".
+ * It's main advantage over "high" resulution shrink is speed, so it's useful, when speed is most
+ * important (preview thumbnails, "map" view, ...).
+ * Method is optimized for RGB24 images.
+ *
+ * \param newx, newy - size of destination image (must be smaller than original!)
+ * \param iDst - pointer to destination image (if it's 0, this image is modified)
+ * \param bChangeBpp - flag points to change result image bpp (if it's true, this result image bpp = 24 (useful for B/W image thumbnails))
+ *
+ * \return true if everything is ok
+ * \author [bd], 9.2004; changes [Artiom Mirolubov], 1.2005
+ */
+bool CxImage::QIShrink(int32_t newx, int32_t newy, CxImage* const iDst, bool bChangeBpp)
+{
+ if (!pDib) return false;
+
+ if (newx>head.biWidth || newy>head.biHeight) {
+ //let me repeat... this method can't enlarge image
+ strcpy(info.szLastError,"QIShrink can't enlarge image");
+ return false;
+ }
+
+ if (newx==head.biWidth && newy==head.biHeight) {
+ //image already correct size (just copy and return)
+ if (iDst) iDst->Copy(*this);
+ return true;
+ }//if
+
+ //create temporary destination image
+ CxImage newImage;
+ newImage.CopyInfo(*this);
+ newImage.Create(newx,newy,(bChangeBpp)?24:head.biBitCount,GetType());
+ newImage.SetPalette(GetPalette());
+ if (!newImage.IsValid()){
+ strcpy(info.szLastError,newImage.GetLastError());
+ return false;
+ }
+
+ //and alpha channel if required
+#if CXIMAGE_SUPPORT_ALPHA
+ if (AlphaIsValid()) newImage.AlphaCreate();
+#endif
+
+ const int32_t oldx = head.biWidth;
+ const int32_t oldy = head.biHeight;
+
+ int32_t accuCellSize = 4;
+#if CXIMAGE_SUPPORT_ALPHA
+ uint8_t *alphaPtr;
+ if (AlphaIsValid()) accuCellSize=5;
+#endif
+
+ uint32_t *accu = new uint32_t[newx*accuCellSize]; //array for suming pixels... one pixel for every destination column
+ uint32_t *accuPtr; //pointer for walking through accu
+ //each cell consists of blue, red, green component and count of pixels summed in this cell
+ memset(accu, 0, newx * accuCellSize * sizeof(uint32_t)); //clear accu
+
+ if (!IsIndexed()) {
+ //RGB24 version with pointers
+ uint8_t *destPtr, *srcPtr, *destPtrS, *srcPtrS; //destination and source pixel, and beginnings of current row
+ srcPtrS=(uint8_t*)BlindGetPixelPointer(0,0);
+ destPtrS=(uint8_t*)newImage.BlindGetPixelPointer(0,0);
+ int32_t ex=0, ey=0; //ex and ey replace division...
+ int32_t dy=0;
+ //(we just add pixels, until by adding newx or newy we get a number greater than old size... then
+ // it's time to move to next pixel)
+
+ for(int32_t y=0; y<oldy; y++){ //for all source rows
+ info.nProgress = (int32_t)(100*y/oldy); if (info.nEscape) break;
+ ey += newy;
+ ex = 0; //restart with ex = 0
+ accuPtr=accu; //restart from beginning of accu
+ srcPtr=srcPtrS; //and from new source line
+#if CXIMAGE_SUPPORT_ALPHA
+ alphaPtr = AlphaGetPointer(0, y);
+#endif
+
+ for(int32_t x=0; x<oldx; x++){ //for all source columns
+ ex += newx;
+ *accuPtr += *(srcPtr++); //add current pixel to current accu slot
+ *(accuPtr+1) += *(srcPtr++);
+ *(accuPtr+2) += *(srcPtr++);
+ (*(accuPtr+3)) ++;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (alphaPtr) *(accuPtr+4) += *(alphaPtr++);
+#endif
+ if (ex>oldx) { //when we reach oldx, it's time to move to new slot
+ accuPtr += accuCellSize;
+ ex -= oldx; //(substract oldx from ex and resume from there on)
+ }//if (ex overflow)
+ }//for x
+
+ if (ey>=oldy) { //now when this happens
+ ey -= oldy; //it's time to move to new destination row
+ destPtr = destPtrS; //reset pointers to proper initial values
+ accuPtr = accu;
+#if CXIMAGE_SUPPORT_ALPHA
+ alphaPtr = newImage.AlphaGetPointer(0, dy++);
+#endif
+ for (int32_t k=0; k<newx; k++) { //copy accu to destination row (divided by number of pixels in each slot)
+ *(destPtr++) = (uint8_t)(*(accuPtr) / *(accuPtr+3));
+ *(destPtr++) = (uint8_t)(*(accuPtr+1) / *(accuPtr+3));
+ *(destPtr++) = (uint8_t)(*(accuPtr+2) / *(accuPtr+3));
+#if CXIMAGE_SUPPORT_ALPHA
+ if (alphaPtr) *(alphaPtr++) = (uint8_t)(*(accuPtr+4) / *(accuPtr+3));
+#endif
+ accuPtr += accuCellSize;
+ }//for k
+ memset(accu, 0, newx * accuCellSize * sizeof(uint32_t)); //clear accu
+ destPtrS += newImage.info.dwEffWidth;
+ }//if (ey overflow)
+
+ srcPtrS += info.dwEffWidth; //next round we start from new source row
+ }//for y
+ } else {
+ //standard version with GetPixelColor...
+ int32_t ex=0, ey=0; //ex and ey replace division...
+ int32_t dy=0;
+ //(we just add pixels, until by adding newx or newy we get a number greater than old size... then
+ // it's time to move to next pixel)
+ RGBQUAD rgb;
+
+ for(int32_t y=0; y<oldy; y++){ //for all source rows
+ info.nProgress = (int32_t)(100*y/oldy); if (info.nEscape) break;
+ ey += newy;
+ ex = 0; //restart with ex = 0
+ accuPtr=accu; //restart from beginning of accu
+ for(int32_t x=0; x<oldx; x++){ //for all source columns
+ ex += newx;
+ rgb = GetPixelColor(x, y, true);
+ *accuPtr += rgb.rgbBlue; //add current pixel to current accu slot
+ *(accuPtr+1) += rgb.rgbRed;
+ *(accuPtr+2) += rgb.rgbGreen;
+ (*(accuPtr+3)) ++;
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha) *(accuPtr+4) += rgb.rgbReserved;
+#endif
+ if (ex>oldx) { //when we reach oldx, it's time to move to new slot
+ accuPtr += accuCellSize;
+ ex -= oldx; //(substract oldx from ex and resume from there on)
+ }//if (ex overflow)
+ }//for x
+
+ if (ey>=oldy) { //now when this happens
+ ey -= oldy; //it's time to move to new destination row
+ accuPtr = accu;
+ for (int32_t dx=0; dx<newx; dx++) { //copy accu to destination row (divided by number of pixels in each slot)
+ rgb.rgbBlue = (uint8_t)(*(accuPtr) / *(accuPtr+3));
+ rgb.rgbRed = (uint8_t)(*(accuPtr+1) / *(accuPtr+3));
+ rgb.rgbGreen= (uint8_t)(*(accuPtr+2) / *(accuPtr+3));
+#if CXIMAGE_SUPPORT_ALPHA
+ if (pAlpha) rgb.rgbReserved = (uint8_t)(*(accuPtr+4) / *(accuPtr+3));
+#endif
+ newImage.SetPixelColor(dx, dy, rgb, pAlpha!=0);
+ accuPtr += accuCellSize;
+ }//for dx
+ memset(accu, 0, newx * accuCellSize * sizeof(uint32_t)); //clear accu
+ dy++;
+ }//if (ey overflow)
+ }//for y
+ }//if
+
+ delete [] accu; //delete helper array
+
+ //copy new image to the destination
+ if (iDst)
+ iDst->Transfer(newImage);
+ else
+ Transfer(newImage);
+ return true;
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_TRANSFORMATION
diff --git a/archive/hge/CxImage/ximawbmp.cpp b/archive/hge/CxImage/ximawbmp.cpp new file mode 100644 index 0000000..7ba5d00 --- /dev/null +++ b/archive/hge/CxImage/ximawbmp.cpp @@ -0,0 +1,134 @@ +/*
+ * File: ximawbmp.cpp
+ * Purpose: Platform Independent WBMP Image Class Loader and Writer
+ * 12/Jul/2002 Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximawbmp.h"
+
+#if CXIMAGE_SUPPORT_WBMP
+
+#include "ximaiter.h"
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageWBMP::Decode(CxFile *hFile)
+{
+ if (hFile == NULL) return false;
+
+ WBMPHEADER wbmpHead;
+
+ cx_try
+ {
+ ReadOctet(hFile, &wbmpHead.Type);
+
+ uint32_t dat;
+ ReadOctet(hFile, &dat);
+ wbmpHead.FixHeader = (uint8_t)dat;
+
+ ReadOctet(hFile, &wbmpHead.ImageWidth);
+ ReadOctet(hFile, &wbmpHead.ImageHeight);
+
+ if (hFile->Eof())
+ cx_throw("Not a WBMP");
+
+ if (wbmpHead.Type != 0)
+ cx_throw("Unsupported WBMP type");
+
+ head.biWidth = wbmpHead.ImageWidth;
+ head.biHeight= wbmpHead.ImageHeight;
+
+ if (head.biWidth<=0 || head.biHeight<=0)
+ cx_throw("Corrupted WBMP");
+
+ if (info.nEscape == -1){
+ info.dwType = CXIMAGE_FORMAT_WBMP;
+ return true;
+ }
+
+ Create(head.biWidth, head.biHeight, 1, CXIMAGE_FORMAT_WBMP);
+ if (!IsValid()) cx_throw("WBMP Create failed");
+ SetGrayPalette();
+
+ int32_t linewidth=(head.biWidth+7)/8;
+ CImageIterator iter(this);
+ iter.Upset();
+ for (int32_t y=0; y < head.biHeight; y++){
+ hFile->Read(iter.GetRow(),linewidth,1);
+ iter.PrevRow();
+ }
+
+ } cx_catch {
+ if (strcmp(message,"")) strncpy(info.szLastError,message,255);
+ return FALSE;
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageWBMP::ReadOctet(CxFile * hFile, uint32_t *data)
+{
+ uint8_t c;
+ *data = 0;
+ do {
+ if (hFile->Eof()) return false;
+ c = (uint8_t)hFile->GetC();
+ *data <<= 7;
+ *data |= (c & 0x7F);
+ } while ((c&0x80)!=0);
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageWBMP::Encode(CxFile * hFile)
+{
+ if (EncodeSafeCheck(hFile)) return false;
+
+ //check format limits
+ if (head.biBitCount!=1){
+ strcpy(info.szLastError,"Can't save this image as WBMP");
+ return false;
+ }
+
+ WBMPHEADER wbmpHead;
+ wbmpHead.Type=0;
+ wbmpHead.FixHeader=0;
+ wbmpHead.ImageWidth=head.biWidth;
+ wbmpHead.ImageHeight=head.biHeight;
+
+ // Write the file header
+ hFile->PutC('\0');
+ hFile->PutC('\0');
+ WriteOctet(hFile,wbmpHead.ImageWidth);
+ WriteOctet(hFile,wbmpHead.ImageHeight);
+ // Write the pixels
+ int32_t linewidth=(wbmpHead.ImageWidth+7)/8;
+ CImageIterator iter(this);
+ iter.Upset();
+ for (uint32_t y=0; y < wbmpHead.ImageHeight; y++){
+ hFile->Write(iter.GetRow(),linewidth,1);
+ iter.PrevRow();
+ }
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageWBMP::WriteOctet(CxFile * hFile, const uint32_t data)
+{
+ int32_t ns = 0;
+ while (data>>(ns+7)) ns+=7;
+ while (ns>0){
+ if (!hFile->PutC(0x80 | (uint8_t)(data>>ns))) return false;
+ ns-=7;
+ }
+ if (!(hFile->PutC((uint8_t)(0x7F & data)))) return false;
+ return true;
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_ENCODE
+////////////////////////////////////////////////////////////////////////////////
+#endif // CXIMAGE_SUPPORT_WBMP
+
diff --git a/archive/hge/CxImage/ximawbmp.h b/archive/hge/CxImage/ximawbmp.h new file mode 100644 index 0000000..9a7837e --- /dev/null +++ b/archive/hge/CxImage/ximawbmp.h @@ -0,0 +1,49 @@ +/*
+ * File: ximawbmp.h
+ * Purpose: WBMP Image Class Loader and Writer
+ */
+/* ==========================================================
+ * CxImageWBMP (c) 12/Jul/2002 Davide Pizzolato - www.xdp.it
+ * For conditions of distribution and use, see copyright notice in ximage.h
+ * ==========================================================
+ */
+#if !defined(__ximaWBMP_h)
+#define __ximaWBMP_h
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_WBMP
+
+class CxImageWBMP: public CxImage
+{
+#pragma pack(1)
+typedef struct tagWbmpHeader
+{
+ uint32_t Type; // 0
+ uint8_t FixHeader; // 0
+ uint32_t ImageWidth; // Image Width
+ uint32_t ImageHeight; // Image Height
+} WBMPHEADER;
+#pragma pack()
+public:
+ CxImageWBMP(): CxImage(CXIMAGE_FORMAT_WBMP) {}
+
+// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_WBMP);}
+// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_WBMP);}
+ bool Decode(CxFile * hFile);
+ bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
+protected:
+ bool ReadOctet(CxFile * hFile, uint32_t *data);
+
+public:
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+protected:
+ bool WriteOctet(CxFile * hFile, const uint32_t data);
+#endif // CXIMAGE_SUPPORT_ENCODE
+};
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximawmf.cpp b/archive/hge/CxImage/ximawmf.cpp new file mode 100644 index 0000000..a1057f5 --- /dev/null +++ b/archive/hge/CxImage/ximawmf.cpp @@ -0,0 +1,483 @@ +/*
+*********************************************************************
+ * File: ximawmf.cpp
+ * Purpose: Windows Metafile Class Loader and Writer
+ * Author: Volker Horch - vhorch@gmx.de
+ * created: 13-Jun-2002
+ *
+ * Note: If the code below works, i wrote it.
+ * If it doesn't work, i don't know who wrote it.
+*********************************************************************
+ */
+
+/*
+*********************************************************************
+ Note by Author:
+*********************************************************************
+
+ Metafile Formats:
+ =================
+
+ There are 2 kinds of Windows Metafiles:
+ - Standard Windows Metafile
+ - Placeable Windows Metafile
+
+ A StandardWindows Metafile looks like:
+ - Metafile Header (MEATAHEADER)
+ - Metafile Records
+
+ A Placeable Metafile looks like:
+ - Aldus Header (METAFILEHEADER)
+ - Metafile Header (METAHEADER)
+ - Metafile Records
+
+ The "Metafile Header" and the "Metafile Records" are the same
+ for both formats. However, the Standard Metafile does not contain any
+ information about the original dimensions or x/y ratio of the Metafile.
+
+ I decided, to allow only placeable Metafiles here. If you also want to
+ enable Standard Metafiles, you will have to guess the dimensions of
+ the image.
+
+*********************************************************************
+ Limitations: see ximawmf.h
+ you may configure some stuff there
+*********************************************************************
+*/
+
+#include "ximawmf.h"
+
+#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+bool CxImageWMF::Decode(CxFile *hFile, int32_t nForceWidth, int32_t nForceHeight)
+{
+ if (hFile == NULL) return false;
+
+ HENHMETAFILE hMeta;
+ HDC hDC;
+ int32_t cx,cy;
+
+ //save the current position of the file
+ int32_t pos = hFile->Tell();
+
+ // Read the Metafile and convert to an Enhanced Metafile
+ METAFILEHEADER mfh;
+ hMeta = ConvertWmfFiletoEmf(hFile, &mfh);
+ if (hMeta) { // ok, it's a WMF
+
+/////////////////////////////////////////////////////////////////////
+// We use the original WMF size information, because conversion to
+// EMF adjusts the Metafile to Full Screen or does not set rclBounds at all
+// ENHMETAHEADER emh;
+// uint32_t uRet;
+// uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
+// sizeof(ENHMETAHEADER), // size of buffer, in bytes
+// &emh); // address of buffer to receive data
+// if (!uRet){
+// DeleteEnhMetaFile(hMeta);
+// return false;
+// }
+// // calculate size
+// cx = emh.rclBounds.right - emh.rclBounds.left;
+// cy = emh.rclBounds.bottom - emh.rclBounds.top;
+/////////////////////////////////////////////////////////////////////
+
+ // calculate size
+ // scale the metafile (pixels/inch of metafile => pixels/inch of display)
+ // mfh.inch already checked to be <> 0
+
+ hDC = ::GetDC(0);
+ int32_t cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ int32_t cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ ::ReleaseDC(0, hDC);
+
+ cx = (mfh.inch/2 + (mfh.bbox.right - mfh.bbox.left) * cx1) / mfh.inch;
+ cy = (mfh.inch/2 + (mfh.bbox.bottom - mfh.bbox.top) * cy1) / mfh.inch;
+
+ } else { // maybe it's an EMF...
+
+ hFile->Seek(pos,SEEK_SET);
+
+ ENHMETAHEADER emh;
+ hMeta = ConvertEmfFiletoEmf(hFile, &emh);
+
+ if (!hMeta){
+ strcpy(info.szLastError,"corrupted WMF");
+ return false; // definitively give up
+ }
+
+ // ok, it's an EMF; calculate canvas size
+ cx = emh.rclBounds.right - emh.rclBounds.left;
+ cy = emh.rclBounds.bottom - emh.rclBounds.top;
+
+ // alternative methods, sometime not so reliable... [DP]
+ //cx = emh.szlDevice.cx;
+ //cy = emh.szlDevice.cy;
+ //
+ //hDC = ::GetDC(0);
+ //float hscale = (float)GetDeviceCaps(hDC, HORZRES)/(100.0f * GetDeviceCaps(hDC, HORZSIZE));
+ //float vscale = (float)GetDeviceCaps(hDC, VERTRES)/(100.0f * GetDeviceCaps(hDC, VERTSIZE));
+ //::ReleaseDC(0, hDC);
+ //cx = (int32_t)((emh.rclFrame.right - emh.rclFrame.left) * hscale);
+ //cy = (int32_t)((emh.rclFrame.bottom - emh.rclFrame.top) * vscale);
+ }
+
+ if (info.nEscape == -1) { // Check if cancelled
+ head.biWidth = cx;
+ head.biHeight= cy;
+ info.dwType = CXIMAGE_FORMAT_WMF;
+ DeleteEnhMetaFile(hMeta);
+ strcpy(info.szLastError,"output dimensions returned");
+ return true;
+ }
+
+ if (!cx || !cy) {
+ DeleteEnhMetaFile(hMeta);
+ strcpy(info.szLastError,"empty WMF");
+ return false;
+ }
+
+ if (nForceWidth) cx=nForceWidth;
+ if (nForceHeight) cy=nForceHeight;
+ ShrinkMetafile(cx, cy); // !! Otherwise Bitmap may have bombastic size
+
+ HDC hDC0 = ::GetDC(0); // DC of screen
+ HBITMAP hBitmap = CreateCompatibleBitmap(hDC0, cx, cy); // has # colors of display
+ hDC = CreateCompatibleDC(hDC0); // memory dc compatible with screen
+ ::ReleaseDC(0, hDC0); // don't need anymore. get rid of it.
+
+ if (hDC){
+ if (hBitmap){
+ RECT rc = {0,0,cx,cy};
+ int32_t bpp = ::GetDeviceCaps(hDC, BITSPIXEL);
+
+ HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDC, hBitmap);
+
+ // clear out the entire bitmap with windows background
+ // because the MetaFile may not contain background information
+ uint32_t dwBack = XMF_COLOR_BACK;
+#if XMF_SUPPORT_TRANSPARENCY
+ if (bpp == 24) dwBack = XMF_COLOR_TRANSPARENT;
+#endif
+ uint32_t OldColor = SetBkColor(hDC, dwBack);
+ ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
+ SetBkColor(hDC, OldColor);
+
+ //retrieves optional palette entries from the specified enhanced metafile
+ PLOGPALETTE plogPal;
+ PBYTE pjTmp;
+ HPALETTE hPal;
+ int32_t iEntries = GetEnhMetaFilePaletteEntries(hMeta, 0, NULL);
+ if (iEntries) {
+ if ((plogPal = (PLOGPALETTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
+ sizeof(uint32_t) + sizeof(PALETTEENTRY)*iEntries )) == NULL) {
+ DeleteObject(hBitmap);
+ DeleteDC(hDC);
+ DeleteEnhMetaFile(hMeta);
+ strcpy(info.szLastError,"Cancelled");
+ return false;
+ }
+
+ plogPal->palVersion = 0x300;
+ plogPal->palNumEntries = (uint16_t) iEntries;
+ pjTmp = (PBYTE) plogPal;
+ pjTmp += 4;
+
+ GetEnhMetaFilePaletteEntries(hMeta, iEntries, (PPALETTEENTRY)pjTmp);
+ hPal = CreatePalette(plogPal);
+ GlobalFree(plogPal);
+
+ SelectPalette(hDC, hPal, FALSE);
+ RealizePalette(hDC);
+ }
+
+ // Play the Metafile into Memory DC
+ BOOL bRet = PlayEnhMetaFile(hDC, // handle to a device context
+ hMeta, // handle to an enhanced metafile
+ &rc); // pointer to bounding rectangle
+
+ SelectObject(hDC, hBitmapOld);
+ DeleteEnhMetaFile(hMeta); // we are done with this one
+
+ if (info.nEscape) { // Check if cancelled
+ DeleteObject(hBitmap);
+ DeleteDC(hDC);
+ strcpy(info.szLastError,"Cancelled");
+ return false;
+ }
+
+ // the Bitmap now has the image.
+ // Create our DIB and convert the DDB into DIB
+ if (!Create(cx, cy, bpp, CXIMAGE_FORMAT_WMF)) {
+ DeleteObject(hBitmap);
+ DeleteDC(hDC);
+ return false;
+ }
+
+#if XMF_SUPPORT_TRANSPARENCY
+ if (bpp == 24) {
+ RGBQUAD rgbTrans = { XMF_RGBQUAD_TRANSPARENT };
+ SetTransColor(rgbTrans);
+ }
+#endif
+ // We're finally ready to get the DIB. Call the driver and let
+ // it party on our bitmap. It will fill in the color table,
+ // and bitmap bits of our global memory block.
+ bRet = GetDIBits(hDC, hBitmap, 0,
+ (uint32_t)cy, GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
+
+ DeleteObject(hBitmap);
+ DeleteDC(hDC);
+
+ return (bRet!=0);
+ } else {
+ DeleteDC(hDC);
+ }
+ } else {
+ if (hBitmap) DeleteObject(hBitmap);
+ }
+
+ DeleteEnhMetaFile(hMeta);
+
+ return false;
+}
+
+/**********************************************************************
+ Function: CheckMetafileHeader
+ Purpose: Check if the Metafileheader of a file is valid
+**********************************************************************/
+BOOL CxImageWMF::CheckMetafileHeader(METAFILEHEADER *metafileheader)
+{
+ uint16_t *pw;
+ uint16_t cs;
+ int32_t i;
+
+ // check magic #
+ if (metafileheader->key != 0x9ac6cdd7L) return false;
+
+ // test checksum of header
+ pw = (uint16_t *)metafileheader;
+ cs = *pw;
+ pw++;
+ for (i = 0; i < 9; i++) {
+ cs ^= *pw;
+ pw++;
+ }
+
+ if (cs != metafileheader->checksum) return false;
+
+ // check resolution
+ if ((metafileheader->inch <= 0) || (metafileheader->inch > 2540)) return false;
+
+ return true;
+}
+
+/**********************************************************************
+ Function: ConvertWmfFiletoEmf
+ Purpose: Converts a Windows Metafile into an Enhanced Metafile
+**********************************************************************/
+HENHMETAFILE CxImageWMF::ConvertWmfFiletoEmf(CxFile *fp, METAFILEHEADER *metafileheader)
+{
+ HENHMETAFILE hMeta;
+ uint32_t lenFile;
+ uint32_t len;
+ uint8_t *p;
+ METAHEADER mfHeader;
+ uint32_t seekpos;
+
+ hMeta = 0;
+
+ // get length of the file
+ lenFile = fp->Size();
+
+ // a placeable metafile starts with a METAFILEHEADER
+ // read it and check metafileheader
+ len = fp->Read(metafileheader, 1, sizeof(METAFILEHEADER));
+ if (len < sizeof(METAFILEHEADER)) return (hMeta);
+
+ if (CheckMetafileHeader(metafileheader)) {
+ // This is a placeable metafile
+ // Convert the placeable format into something that can
+ // be used with GDI metafile functions
+ seekpos = sizeof(METAFILEHEADER);
+ } else {
+ // Not a placeable wmf. A windows metafile?
+ // at least not scaleable.
+ // we could try to convert, but would loose ratio. don't allow this
+ return (hMeta);
+
+ //metafileheader->bbox.right = ?;
+ //metafileheader->bbox.left = ?;
+ //metafileheader->bbox.bottom = ?;
+ //metafileheader->bbox.top = ?;
+ //metafileheader->inch = ?;
+ //
+ //seekpos = 0;
+ // fp->Seek(0, SEEK_SET); // rewind
+ }
+
+ // At this point we have a metaheader regardless of whether
+ // the metafile was a windows metafile or a placeable metafile
+ // so check to see if it is valid. There is really no good
+ // way to do this so just make sure that the mtType is either
+ // 1 or 2 (memory or disk file)
+ // in addition we compare the length of the METAHEADER against
+ // the length of the file. if filelength < len => no Metafile
+
+ len = fp->Read(&mfHeader, 1, sizeof(METAHEADER));
+ if (len < sizeof(METAHEADER)) return (hMeta);
+
+ if ((mfHeader.mtType != 1) && (mfHeader.mtType != 2)) return (hMeta);
+
+ // Length in Bytes from METAHEADER
+ len = mfHeader.mtSize * 2;
+ if (len > lenFile) return (hMeta);
+
+ // Allocate memory for the metafile bits
+ p = (uint8_t *)malloc(len);
+ if (!p) return (hMeta);
+
+ // seek back to METAHEADER and read all the stuff at once
+ fp->Seek(seekpos, SEEK_SET);
+ lenFile = fp->Read(p, 1, len);
+ if (lenFile != len) {
+ free(p);
+ return (hMeta);
+ }
+
+ // the following (commented code) works, but adjusts rclBound of the
+ // Enhanced Metafile to full screen.
+ // the METAFILEHEADER from above is needed to scale the image
+
+// hMeta = SetWinMetaFileBits(len, p, NULL, NULL);
+
+ // scale the metafile (pixels/inch of metafile => pixels/inch of display)
+
+ METAFILEPICT mfp;
+ int32_t cx1, cy1;
+ HDC hDC;
+
+ hDC = ::GetDC(0);
+ cx1 = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ cy1 = ::GetDeviceCaps(hDC, LOGPIXELSY);
+
+ memset(&mfp, 0, sizeof(mfp));
+
+ mfp.mm = MM_ANISOTROPIC;
+ mfp.xExt = 10000; //(metafileheader->bbox.right - metafileheader->bbox.left) * cx1 / metafileheader->inch;
+ mfp.yExt = 10000; //(metafileheader->bbox.bottom - metafileheader->bbox.top) * cy1 / metafileheader->inch;
+ mfp.hMF = 0;
+
+ // in MM_ANISOTROPIC mode xExt and yExt are in MM_HIENGLISH
+ // MM_HIENGLISH means: Each logical unit is converted to 0.001 inch
+ //mfp.xExt *= 1000;
+ //mfp.yExt *= 1000;
+ // ????
+ //int32_t k = 332800 / ::GetSystemMetrics(SM_CXSCREEN);
+ //mfp.xExt *= k; mfp.yExt *= k;
+
+ // fix for Win9x
+ while ((mfp.xExt < 6554) && (mfp.yExt < 6554))
+ {
+ mfp.xExt *= 10;
+ mfp.yExt *= 10;
+ }
+
+ hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
+
+ if (!hMeta){ //try 2nd conversion using a different mapping
+ mfp.mm = MM_TEXT;
+ hMeta = SetWinMetaFileBits(len, p, hDC, &mfp);
+ }
+
+ ::ReleaseDC(0, hDC);
+
+ // Free Memory
+ free(p);
+
+ return (hMeta);
+}
+/////////////////////////////////////////////////////////////////////
+HENHMETAFILE CxImageWMF::ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh)
+{
+ HENHMETAFILE hMeta;
+ int32_t iLen = pFile->Size();
+
+ // Check the header first: <km>
+ int32_t pos = pFile->Tell();
+ int32_t iLenRead = pFile->Read(pemfh, 1, sizeof(ENHMETAHEADER));
+ if (iLenRead < sizeof(ENHMETAHEADER)) return NULL;
+ if (pemfh->iType != EMR_HEADER) return NULL;
+ if (pemfh->dSignature != ENHMETA_SIGNATURE) return NULL;
+ //if (pemfh->nBytes != (uint32_t)iLen) return NULL;
+ pFile->Seek(pos,SEEK_SET);
+
+ uint8_t* pBuff = (uint8_t *)malloc(iLen);
+ if (!pBuff) return (FALSE);
+
+ // Read the Enhanced Metafile
+ iLenRead = pFile->Read(pBuff, 1, iLen);
+ if (iLenRead != iLen) {
+ free(pBuff);
+ return NULL;
+ }
+
+ // Make it a Memory Metafile
+ hMeta = SetEnhMetaFileBits(iLen, pBuff);
+
+ free(pBuff); // finished with this one
+
+ if (!hMeta) return NULL; // oops.
+
+ // Get the Enhanced Metafile Header
+ uint32_t uRet = GetEnhMetaFileHeader(hMeta, // handle of enhanced metafile
+ sizeof(ENHMETAHEADER), // size of buffer, in bytes
+ pemfh); // address of buffer to receive data
+
+ if (!uRet) {
+ DeleteEnhMetaFile(hMeta);
+ return NULL;
+ }
+
+ return (hMeta);
+}
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_DECODE
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_ENCODE
+/////////////////////////////////////////////////////////////////////
+bool CxImageWMF::Encode(CxFile * hFile)
+{
+ if (hFile == NULL) return false;
+ strcpy(info.szLastError, "Save WMF not supported");
+ return false;
+}
+#endif // CXIMAGE_SUPPORT_ENCODE
+/////////////////////////////////////////////////////////////////////
+
+/**********************************************************************
+Function: ShrinkMetafile
+Purpose: Shrink the size of a metafile to be not larger than
+ the definition
+**********************************************************************/
+void CxImageWMF::ShrinkMetafile(int32_t &cx, int32_t &cy)
+{
+ int32_t xScreen = XMF_MAXSIZE_CX;
+ int32_t yScreen = XMF_MAXSIZE_CY;
+
+ if (cx > xScreen){
+ cy = cy * xScreen / cx;
+ cx = xScreen;
+ }
+
+ if (cy > yScreen){
+ cx = cx * yScreen / cy;
+ cy = yScreen;
+ }
+}
+
+#endif // CIMAGE_SUPPORT_WMF
+
diff --git a/archive/hge/CxImage/ximawmf.h b/archive/hge/CxImage/ximawmf.h new file mode 100644 index 0000000..94fb168 --- /dev/null +++ b/archive/hge/CxImage/ximawmf.h @@ -0,0 +1,154 @@ +/*
+*********************************************************************
+ * File: ximawmf.h
+ * Purpose: Windows Metafile Class Loader and Writer
+ * Author: Volker Horch - vhorch@gmx.de
+ * created: 13-Jun-2002
+*********************************************************************
+ */
+
+/*
+*********************************************************************
+ Notes by Author:
+*********************************************************************
+
+ Limitations:
+ ============
+
+ a) Transparency:
+
+ A Metafile is vector graphics, which has transparency by design.
+ This class always converts into a Bitmap format. Transparency is
+ supported, but there is no good way to find out, which parts
+ of the Metafile are transparent. There are two ways how we can
+ handle this:
+
+ - Clear the Background of the Bitmap with the background color
+ you like (i have used COLOR_WINDOW) and don't support transparency.
+
+ below #define XMF_SUPPORT_TRANSPARENCY 0
+ #define XMF_COLOR_BACK RGB(Background color you like)
+
+ - Clear the Background of the Bitmap with a very unusual color
+ (which one ?) and use this color as the transparent color
+
+ below #define XMF_SUPPORT_TRANSPARENCY 1
+ #define XMF_COLOR_TRANSPARENT_R ...
+ #define XMF_COLOR_TRANSPARENT_G ...
+ #define XMF_COLOR_TRANSPARENT_B ...
+
+ b) Resolution
+
+ Once we have converted the Metafile into a Bitmap and we zoom in
+ or out, the image may not look very good. If we still had the
+ original Metafile, zooming would produce good results always.
+
+ c) Size
+
+ Although the filesize of a Metafile may be very small, it might
+ produce a Bitmap with a bombastic size. Assume you have a Metafile
+ with an image size of 6000*4000, which contains just one Metafile
+ record ((e.g. a line from (0,0) to (6000, 4000)). The filesize
+ of this Metafile would be let's say 100kB. If we convert it to
+ a 6000*4000 Bitmap with 24 Bits/Pixes, the Bitmap would consume
+ about 68MB of memory.
+
+ I have choosen, to limit the size of the Bitmap to max.
+ screensize, to avoid memory problems.
+
+ If you want something else,
+ modify #define XMF_MAXSIZE_CX / XMF_MAXSIZE_CY below
+
+*********************************************************************
+*/
+
+#ifndef _XIMAWMF_H
+#define _XIMAWMF_H
+
+#include "ximage.h"
+
+#if CXIMAGE_SUPPORT_WMF && CXIMAGE_SUPPORT_WINDOWS
+
+class CxImageWMF: public CxImage
+{
+
+#pragma pack(1)
+
+typedef struct tagRECT16
+{
+ int16_t left;
+ int16_t top;
+ int16_t right;
+ int16_t bottom;
+} RECT16;
+
+// taken from Windos 3.11 SDK Documentation (Programmer's Reference Volume 4: Resources)
+typedef struct tagMETAFILEHEADER
+{
+ uint32_t key; // always 0x9ac6cdd7
+ uint16_t reserved1; // reserved = 0
+ RECT16 bbox; // bounding rectangle in metafile units as defined in "inch"
+ uint16_t inch; // number of metafile units per inch (should be < 1440)
+ uint32_t reserved2; // reserved = 0
+ uint16_t checksum; // sum of the first 10 WORDS (using XOR operator)
+} METAFILEHEADER;
+
+#pragma pack()
+
+public:
+ CxImageWMF(): CxImage(CXIMAGE_FORMAT_WMF) { }
+
+ bool Decode(CxFile * hFile, int32_t nForceWidth=0, int32_t nForceHeight=0);
+ bool Decode(FILE *hFile, int32_t nForceWidth=0, int32_t nForceHeight=0)
+ { CxIOFile file(hFile); return Decode(&file,nForceWidth,nForceHeight); }
+
+#if CXIMAGE_SUPPORT_ENCODE
+ bool Encode(CxFile * hFile);
+ bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
+#endif // CXIMAGE_SUPPORT_ENCODE
+
+protected:
+ void ShrinkMetafile(int32_t &cx, int32_t &cy);
+ BOOL CheckMetafileHeader(METAFILEHEADER *pmetafileheader);
+ HENHMETAFILE ConvertWmfFiletoEmf(CxFile *pFile, METAFILEHEADER *pmetafileheader);
+ HENHMETAFILE ConvertEmfFiletoEmf(CxFile *pFile, ENHMETAHEADER *pemfh);
+
+};
+
+#define METAFILEKEY 0x9ac6cdd7L
+
+// Background color definition (if no transparency). see Notes above
+#define XMF_COLOR_BACK GetSysColor(COLOR_WINDOW)
+// alternatives
+//#define XMF_COLOR_BACK RGB(192, 192, 192) // lite gray
+//#define XMF_COLOR_BACK RGB( 0, 0, 0) // black
+//#define XMF_COLOR_BACK RGB(255, 255, 255) // white
+
+
+// transparency support. see Notes above
+#define XMF_SUPPORT_TRANSPARENCY 0
+#define XMF_COLOR_TRANSPARENT_R 211
+#define XMF_COLOR_TRANSPARENT_G 121
+#define XMF_COLOR_TRANSPARENT_B 112
+// don't change
+#define XMF_COLOR_TRANSPARENT RGB (XMF_COLOR_TRANSPARENT_R, \
+ XMF_COLOR_TRANSPARENT_G, \
+ XMF_COLOR_TRANSPARENT_B)
+// don't change
+#define XMF_RGBQUAD_TRANSPARENT XMF_COLOR_TRANSPARENT_B, \
+ XMF_COLOR_TRANSPARENT_G, \
+ XMF_COLOR_TRANSPARENT_R, \
+ 0
+// max. size. see Notes above
+// alternatives
+//#define XMF_MAXSIZE_CX (GetSystemMetrics(SM_CXSCREEN)-10)
+//#define XMF_MAXSIZE_CY (GetSystemMetrics(SM_CYSCREEN)-50)
+//#define XMF_MAXSIZE_CX (2*GetSystemMetrics(SM_CXSCREEN)/3)
+//#define XMF_MAXSIZE_CY (2*GetSystemMetrics(SM_CYSCREEN)/3)
+#define XMF_MAXSIZE_CX 4000
+#define XMF_MAXSIZE_CY 4000
+
+
+#endif
+
+#endif
diff --git a/archive/hge/CxImage/ximawnd.cpp b/archive/hge/CxImage/ximawnd.cpp new file mode 100644 index 0000000..7f23f8f --- /dev/null +++ b/archive/hge/CxImage/ximawnd.cpp @@ -0,0 +1,1900 @@ +// xImaWnd.cpp : Windows functions
+/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
+ * CxImage version 7.0.0 31/Dec/2010
+ */
+
+#include "ximage.h"
+
+#include "ximaiter.h"
+#include "ximabmp.h"
+
+////////////////////////////////////////////////////////////////////////////////
+#if defined (_WIN32_WCE)
+
+#ifndef DEFAULT_GUI_FONT
+#define DEFAULT_GUI_FONT 17
+#endif
+
+#ifndef PROOF_QUALITY
+#define PROOF_QUALITY 2
+#endif
+
+struct DIBINFO : public BITMAPINFO
+{
+ RGBQUAD arColors[255]; // Color table info - adds an extra 255 entries to palette
+ operator LPBITMAPINFO() { return (LPBITMAPINFO) this; }
+ operator LPBITMAPINFOHEADER() { return &bmiHeader; }
+ RGBQUAD* ColorTable() { return bmiColors; }
+};
+
+int32_t BytesPerLine(int32_t nWidth, int32_t nBitsPerPixel)
+{
+ return ( (nWidth * nBitsPerPixel + 31) & (~31) ) / 8;
+}
+
+int32_t NumColorEntries(int32_t nBitsPerPixel, int32_t nCompression, uint32_t biClrUsed)
+{
+ int32_t nColors = 0;
+ switch (nBitsPerPixel)
+ {
+ case 1:
+ nColors = 2; break;
+ case 2:
+ nColors = 4; break; // winCE only
+ case 4:
+ nColors = 16; break;
+ case 8:
+ nColors =256; break;
+ case 24:
+ nColors = 0; break;
+ case 16:
+ case 32:
+ nColors = 3; break; // I've found that PocketPCs need this regardless of BI_RGB or BI_BITFIELDS
+ default:
+ ASSERT(FALSE);
+ }
+ // If biClrUsed is provided, and it is a legal value, use it
+ if (biClrUsed > 0 && biClrUsed <= (uint32_t)nColors)
+ return biClrUsed;
+
+ return nColors;
+}
+
+int32_t GetDIBits(
+ HDC hdc, // handle to DC
+ HBITMAP hbmp, // handle to bitmap
+ uint32_t uStartScan, // first scan line to set
+ uint32_t cScanLines, // number of scan lines to copy
+ LPVOID lpvBits, // array for bitmap bits
+ LPBITMAPINFO lpbi, // bitmap data buffer
+ uint32_t uUsage // RGB or palette index
+)
+{
+ uint32_t iColorTableSize = 0;
+
+ if (!hbmp)
+ return 0;
+
+ // Get dimensions of bitmap
+ BITMAP bm;
+ if (!::GetObject(hbmp, sizeof(bm),(LPVOID)&bm))
+ return 0;
+
+ //3. Creating new bitmap and receive pointer to it's bits.
+ HBITMAP hTargetBitmap;
+ void *pBuffer;
+
+ //3.1 Initilize DIBINFO structure
+ DIBINFO dibInfo;
+ dibInfo.bmiHeader.biBitCount = 24;
+ dibInfo.bmiHeader.biClrImportant = 0;
+ dibInfo.bmiHeader.biClrUsed = 0;
+ dibInfo.bmiHeader.biCompression = 0;
+ dibInfo.bmiHeader.biHeight = bm.bmHeight;
+ dibInfo.bmiHeader.biPlanes = 1;
+ dibInfo.bmiHeader.biSize = 40;
+ dibInfo.bmiHeader.biSizeImage = bm.bmHeight*BytesPerLine(bm.bmWidth,24);
+ dibInfo.bmiHeader.biWidth = bm.bmWidth;
+ dibInfo.bmiHeader.biXPelsPerMeter = 3780;
+ dibInfo.bmiHeader.biYPelsPerMeter = 3780;
+ dibInfo.bmiColors[0].rgbBlue = 0;
+ dibInfo.bmiColors[0].rgbGreen = 0;
+ dibInfo.bmiColors[0].rgbRed = 0;
+ dibInfo.bmiColors[0].rgbReserved = 0;
+
+ //3.2 Create bitmap and receive pointer to points into pBuffer
+ HDC hDC = ::GetDC(NULL);
+ ASSERT(hDC);
+ hTargetBitmap = CreateDIBSection(
+ hDC,
+ (const BITMAPINFO*)dibInfo,
+ DIB_RGB_COLORS,
+ (void**)&pBuffer,
+ NULL,
+ 0);
+
+ ::ReleaseDC(NULL, hDC);
+
+ //4. Copy source bitmap into the target bitmap.
+
+ //4.1 Create 2 device contexts
+ HDC memDc = CreateCompatibleDC(NULL);
+ if (!memDc) {
+ ASSERT(FALSE);
+ }
+
+ HDC targetDc = CreateCompatibleDC(NULL);
+ if (!targetDc) {
+ ASSERT(FALSE);
+ }
+
+ //4.2 Select source bitmap into one DC, target into another
+ HBITMAP hOldBitmap1 = (HBITMAP)::SelectObject(memDc, hbmp);
+ HBITMAP hOldBitmap2 = (HBITMAP)::SelectObject(targetDc, hTargetBitmap);
+
+ //4.3 Copy source bitmap into the target one
+ BitBlt(targetDc, 0, 0, bm.bmWidth, bm.bmHeight, memDc, 0, 0, SRCCOPY);
+
+ //4.4 Restore device contexts
+ ::SelectObject(memDc, hOldBitmap1);
+ ::SelectObject(targetDc, hOldBitmap2);
+ DeleteDC(memDc);
+ DeleteDC(targetDc);
+
+ //Here we can bitmap bits: pBuffer. Note:
+ // 1. pBuffer contains 3 bytes per point
+ // 2. Lines ane from the bottom to the top!
+ // 3. Points in the line are from the left to the right
+ // 4. Bytes in one point are BGR (blue, green, red) not RGB
+ // 5. Don't delete pBuffer, it will be automatically deleted
+ // when delete hTargetBitmap
+ lpvBits = pBuffer;
+
+ DeleteObject(hbmp);
+ //DeleteObject(hTargetBitmap);
+
+ return 1;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+#if CXIMAGE_SUPPORT_WINDOWS
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::Blt(HDC pDC, int32_t x, int32_t y)
+{
+ if((pDib==0)||(pDC==0)||(!info.bEnabled)) return 0;
+
+ HBRUSH brImage = CreateDIBPatternBrushPt(pDib, DIB_RGB_COLORS);
+ POINT pt;
+ SetBrushOrgEx(pDC,x,y,&pt); //<RT>
+ HBRUSH brOld = (HBRUSH) SelectObject(pDC, brImage);
+ PatBlt(pDC, x, y, head.biWidth, head.biHeight, PATCOPY);
+ SelectObject(pDC, brOld);
+ SetBrushOrgEx(pDC,pt.x,pt.y,NULL);
+ DeleteObject(brImage);
+ return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Transfer the image in a global bitmap handle (clipboard copy)
+ */
+HANDLE CxImage::CopyToHandle()
+{
+ HANDLE hMem=NULL;
+ if (pDib){
+ hMem= GlobalAlloc(GHND, GetSize());
+ if (hMem){
+ uint8_t* pDst=(uint8_t*)GlobalLock(hMem);
+ if (pDst){
+ memcpy(pDst,pDib,GetSize());
+ }
+ GlobalUnlock(hMem);
+ }
+ }
+ return hMem;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Global object (clipboard paste) constructor
+ * \param hMem: source bitmap object, the clipboard format must be CF_DIB
+ * \return true if everything is ok
+ */
+bool CxImage::CreateFromHANDLE(HANDLE hMem)
+{
+ if (!Destroy())
+ return false;
+
+ uint32_t dwSize = GlobalSize(hMem);
+ if (!dwSize) return false;
+
+ uint8_t *lpVoid; //pointer to the bitmap
+ lpVoid = (uint8_t *)GlobalLock(hMem);
+ BITMAPINFOHEADER *pHead; //pointer to the bitmap header
+ pHead = (BITMAPINFOHEADER *)lpVoid;
+ if (lpVoid){
+
+ //CxMemFile hFile(lpVoid,dwSize);
+
+ //copy the bitmap header
+ memcpy(&head,pHead,sizeof(BITMAPINFOHEADER));
+ //check if it's a top-down bitmap
+ bool bTopDownDib = head.biHeight<0;
+ if (bTopDownDib) head.biHeight=-head.biHeight;
+ //create the image
+ if(!Create(head.biWidth,head.biHeight,head.biBitCount)){
+ GlobalUnlock(hMem);
+ return false;
+ }
+ //preserve DPI
+ SetXDPI((int32_t)floor(head.biXPelsPerMeter * 254.0 / 10000.0 + 0.5));
+ SetYDPI((int32_t)floor(head.biYPelsPerMeter * 254.0 / 10000.0 + 0.5));
+
+ /*//copy the pixels (old way)
+ if((pHead->biCompression != BI_RGB) || (pHead->biBitCount == 32)){ //<Jörgen Alfredsson>
+ // BITFIELD case
+ // set the internal header in the dib
+ memcpy(pDib,&head,sizeof(head));
+ // get the bitfield masks
+ uint32_t bf[3];
+ memcpy(bf,lpVoid+pHead->biSize,12);
+ // transform into RGB
+ Bitfield2RGB(lpVoid+pHead->biSize+12,bf[0],bf[1],bf[2],(uint8_t)pHead->biBitCount);
+ } else { //normal bitmap
+ memcpy(pDib,lpVoid,GetSize());
+ }*/
+
+ // <Michael Gandyra>
+ // fill in color map
+ bool bIsOldBmp = (head.biSize == sizeof(BITMAPCOREHEADER));
+ RGBQUAD *pRgb = GetPalette();
+ if (pRgb) {
+ // number of colors to fill in
+ int32_t nColors = DibNumColors(pHead);
+ if (bIsOldBmp) {
+ /* get pointer to BITMAPCOREINFO (old style 1.x) */
+ LPBITMAPCOREINFO lpbmc = (LPBITMAPCOREINFO)lpVoid;
+ for (int32_t i = nColors - 1; i >= 0; i--) {
+ pRgb[i].rgbRed = lpbmc->bmciColors[i].rgbtRed;
+ pRgb[i].rgbGreen = lpbmc->bmciColors[i].rgbtGreen;
+ pRgb[i].rgbBlue = lpbmc->bmciColors[i].rgbtBlue;
+ pRgb[i].rgbReserved = (uint8_t)0;
+ }
+ } else {
+ /* get pointer to BITMAPINFO (new style 3.x) */
+ LPBITMAPINFO lpbmi = (LPBITMAPINFO)lpVoid;
+ for (int32_t i = nColors - 1; i >= 0; i--) {
+ pRgb[i].rgbRed = lpbmi->bmiColors[i].rgbRed;
+ pRgb[i].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
+ pRgb[i].rgbBlue = lpbmi->bmiColors[i].rgbBlue;
+ pRgb[i].rgbReserved = (uint8_t)0;
+ }
+ }
+ }
+
+ // <Michael Gandyra>
+ uint32_t dwCompression = pHead->biCompression;
+ // compressed bitmap ?
+ if(dwCompression!=BI_RGB || pHead->biBitCount==32 || pHead->biBitCount ==16) {
+ // get the bitmap bits
+ LPSTR lpDIBBits = (LPSTR)((uint8_t*)pHead + *(uint32_t*)pHead + (uint16_t)(GetNumColors() * sizeof(RGBQUAD)));
+ // decode and copy them to our image
+ switch (pHead->biBitCount) {
+ case 32 :
+ {
+ // BITFIELD case
+ if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB) {
+ // get the bitfield masks
+ uint32_t bf[3];
+ memcpy(bf,lpVoid+pHead->biSize,12);
+ // transform into RGB
+ Bitfield2RGB(lpVoid+pHead->biSize+12,bf[0],bf[1],bf[2],(uint8_t)pHead->biBitCount);
+ } else {
+ // "unknown compression";
+ GlobalUnlock(hMem);
+ return false;
+ }
+ }
+ break;
+ case 16 :
+ {
+ // get the bitfield masks
+ int32_t offset=0;
+ uint32_t bf[3];
+ if (dwCompression == BI_BITFIELDS) {
+ memcpy(bf,lpVoid+pHead->biSize,12);
+ offset= 12;
+ } else {
+ bf[0] = 0x7C00;
+ bf[1] = 0x3E0;
+ bf[2] = 0x1F; // RGB555
+ }
+ // copy the pixels
+ memcpy(info.pImage, lpDIBBits + offset, head.biHeight*((head.biWidth+1)/2)*4);
+ // transform into RGB
+ Bitfield2RGB(info.pImage, bf[0], bf[1], bf[2], 16);
+ }
+ break;
+ case 8 :
+ case 4 :
+ case 1 :
+ {
+ switch (dwCompression) {
+ case BI_RLE4:
+ {
+ uint8_t status_byte = 0;
+ uint8_t second_byte = 0;
+ int32_t scanline = 0;
+ int32_t bits = 0;
+ BOOL low_nibble = FALSE;
+ CImageIterator iter(this);
+
+ for (BOOL bContinue = TRUE; bContinue; ) {
+ status_byte = *(lpDIBBits++);
+ switch (status_byte) {
+ case RLE_COMMAND :
+ status_byte = *(lpDIBBits++);
+ switch (status_byte) {
+ case RLE_ENDOFLINE :
+ bits = 0;
+ scanline++;
+ low_nibble = FALSE;
+ break;
+ case RLE_ENDOFBITMAP :
+ bContinue = FALSE;
+ break;
+ case RLE_DELTA :
+ {
+ // read the delta values
+ uint8_t delta_x;
+ uint8_t delta_y;
+ delta_x = *(lpDIBBits++);
+ delta_y = *(lpDIBBits++);
+ // apply them
+ bits += delta_x / 2;
+ scanline += delta_y;
+ break;
+ }
+ default :
+ second_byte = *(lpDIBBits++);
+ uint8_t* sline = iter.GetRow(scanline);
+ for (int32_t i = 0; i < status_byte; i++) {
+ if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
+ if (low_nibble) {
+ if (i&1)
+ *(sline + bits) |= (second_byte & 0x0f);
+ else
+ *(sline + bits) |= (second_byte & 0xf0)>>4;
+ bits++;
+ } else {
+ if (i&1)
+ *(sline + bits) = (uint8_t)(second_byte & 0x0f)<<4;
+ else
+ *(sline + bits) = (uint8_t)(second_byte & 0xf0);
+ }
+ }
+
+ if ((i & 1) && (i != (status_byte - 1)))
+ second_byte = *(lpDIBBits++);
+
+ low_nibble = !low_nibble;
+ }
+ if ((((status_byte+1) >> 1) & 1 ) == 1)
+ second_byte = *(lpDIBBits++);
+ break;
+ };
+ break;
+ default :
+ {
+ uint8_t* sline = iter.GetRow(scanline);
+ second_byte = *(lpDIBBits++);
+ for (unsigned i = 0; i < status_byte; i++) {
+ if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
+ if (low_nibble) {
+ if (i&1)
+ *(sline + bits) |= (second_byte & 0x0f);
+ else
+ *(sline + bits) |= (second_byte & 0xf0)>>4;
+ bits++;
+ } else {
+ if (i&1)
+ *(sline + bits) = (uint8_t)(second_byte & 0x0f)<<4;
+ else
+ *(sline + bits) = (uint8_t)(second_byte & 0xf0);
+ }
+ }
+ low_nibble = !low_nibble;
+ }
+ }
+ break;
+ };
+ }
+ }
+ break;
+ case BI_RLE8 :
+ {
+ uint8_t status_byte = 0;
+ uint8_t second_byte = 0;
+ int32_t scanline = 0;
+ int32_t bits = 0;
+ CImageIterator iter(this);
+
+ for (BOOL bContinue = TRUE; bContinue; ) {
+ status_byte = *(lpDIBBits++);
+ if (status_byte==RLE_COMMAND) {
+ status_byte = *(lpDIBBits++);
+ switch (status_byte) {
+ case RLE_ENDOFLINE :
+ bits = 0;
+ scanline++;
+ break;
+ case RLE_ENDOFBITMAP :
+ bContinue = FALSE;
+ break;
+ case RLE_DELTA :
+ {
+ // read the delta values
+ uint8_t delta_x;
+ uint8_t delta_y;
+ delta_x = *(lpDIBBits++);
+ delta_y = *(lpDIBBits++);
+ // apply them
+ bits += delta_x;
+ scanline += delta_y;
+ }
+ break;
+ default :
+ int32_t nNumBytes = sizeof(uint8_t) * status_byte;
+ memcpy((void *)(iter.GetRow(scanline) + bits), lpDIBBits, nNumBytes);
+ lpDIBBits += nNumBytes;
+ // align run length to even number of bytes
+ if ((status_byte & 1) == 1)
+ second_byte = *(lpDIBBits++);
+ bits += status_byte;
+ break;
+ };
+ } else {
+ uint8_t *sline = iter.GetRow(scanline);
+ second_byte = *(lpDIBBits++);
+ for (unsigned i = 0; i < status_byte; i++) {
+ if ((uint8_t*)(sline+bits) < (uint8_t*)(info.pImage+head.biSizeImage)){
+ *(sline + bits) = second_byte;
+ bits++;
+ } else {
+ bContinue = FALSE; //don't delete: we are in memory, it is not as with files
+ break;
+ }
+ }
+ }
+ }
+ }
+ break;
+ default :
+ {
+ // "compression type not supported";
+ GlobalUnlock(hMem);
+ return false;
+ }
+ }
+ }
+ }
+ } else {
+ //normal bitmap (not compressed)
+ memcpy(pDib,lpVoid,GetSize());
+ }
+
+ GlobalUnlock(hMem);
+
+ if (bTopDownDib) Flip();
+
+ return true;
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Transfer the image in a icon handle, with transparency.
+ * \param hdc: target device context (the screen, usually)
+ * \param bTransparency : (optional) exports trancparency
+ * \return icon handle, or NULL if an error occurs.
+ * \sa MakeBitmap
+ * \author [brunom]
+ */
+HICON CxImage::MakeIcon(HDC hdc, bool bTransparency)
+{
+ HICON hDestIcon = 0;
+
+ ICONINFO csDest;
+
+ csDest.fIcon = TRUE;
+ csDest.xHotspot = 0;
+ csDest.yHotspot = 0;
+
+ // Assign HBITMAP with Transparency to ICON Info structure
+ csDest.hbmColor = MakeBitmap( hdc, bTransparency );
+
+ // Create Mask just in case we need a Mask for the Icons
+ CxImage a_Mask;
+ GetTransparentMask(&a_Mask);
+
+ // Assign Mask
+ csDest.hbmMask = a_Mask.MakeBitmap();
+
+ // Create Icon
+ hDestIcon = ::CreateIconIndirect(&csDest);
+
+ return hDestIcon;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Transfer the image in a bitmap handle
+ * \param hdc: target device context (the screen, usually)
+ * \param bTransparency : (optional) exports trancparency
+ * \return bitmap handle, or NULL if an error occurs.
+ * \sa Draw2HBITMAP, MakeIcon
+ * \author []; changes [brunom]
+ */
+HBITMAP CxImage::MakeBitmap(HDC hdc, bool bTransparency)
+{
+ if (!pDib)
+ return NULL;
+
+ // Create HBITMAP with Trancparency
+ if( (pAlpha!=0) && bTransparency )
+ {
+ HDC hMemDC;
+ if (hdc)
+ hMemDC = hdc;
+ else
+ hMemDC = CreateCompatibleDC(NULL);
+
+ BITMAPINFO bi;
+
+ // Fill in the BITMAPINFOHEADER
+ bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bi.bmiHeader.biWidth = GetWidth();
+ bi.bmiHeader.biHeight = GetHeight();
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 4 * GetWidth() * GetHeight();
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+ bi.bmiHeader.biClrImportant = 0;
+
+ COLORREF* pCrBits = NULL;
+ HBITMAP hbmp = CreateDIBSection (
+ hMemDC, &bi, DIB_RGB_COLORS, (void **)&pCrBits,
+ NULL, NULL);
+
+ if (!hdc)
+ DeleteDC(hMemDC);
+
+ DIBSECTION ds;
+ if (::GetObject (hbmp, sizeof (DIBSECTION), &ds) == 0)
+ {
+ return 0;
+ }
+
+ // transfer Pixels from CxImage to Bitmap
+ RGBQUAD* pBit = (RGBQUAD*) ds.dsBm.bmBits;
+ int32_t lPx,lPy;
+ for( lPy=0 ; lPy < bi.bmiHeader.biHeight ; ++lPy )
+ {
+ for( lPx=0 ; lPx < bi.bmiHeader.biWidth ; ++lPx )
+ {
+ RGBQUAD lPixel = GetPixelColor(lPx,lPy,true);
+ *pBit = lPixel;
+ pBit++;
+ }
+ }
+
+ return hbmp;
+ }
+
+ // Create HBITMAP without Trancparency
+ if (!hdc){
+ // this call to CreateBitmap doesn't create a DIB <jaslet>
+ // // Create a device-independent bitmap <CSC>
+ // return CreateBitmap(head.biWidth,head.biHeight, 1, head.biBitCount, GetBits());
+ // use instead this code
+ HDC hMemDC = CreateCompatibleDC(NULL);
+ LPVOID pBit32;
+ HBITMAP bmp = CreateDIBSection(hMemDC,(LPBITMAPINFO)pDib,DIB_RGB_COLORS, &pBit32, NULL, 0);
+ if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);
+ DeleteDC(hMemDC);
+ return bmp;
+ }
+
+ // this single line seems to work very well
+ //HBITMAP bmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)pDib, CBM_INIT,
+ // GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
+ // this alternative works also with _WIN32_WCE
+ LPVOID pBit32;
+ HBITMAP bmp = CreateDIBSection(hdc, (LPBITMAPINFO)pDib, DIB_RGB_COLORS, &pBit32, NULL, 0);
+ if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);
+
+ return bmp;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * check if the bitmap contains transparency data
+ * \param hbmp : bitmap resource handle
+ * \return true the bitmap has transparency
+ * \author [brunom]
+ */
+bool CxImage::IsHBITMAPAlphaValid( HBITMAP hbmp )
+{
+ bool lbAlphaValid = false;
+ if (hbmp)
+ {
+ BITMAP bm;
+ // get informations about the bitmap
+ GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
+
+ // for alpha there must bee 32 Bit's per Pixel ??
+ if( bm.bmBitsPixel == 32 )
+ {
+ BITMAPINFO l_BitmapInfo;
+ l_BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ l_BitmapInfo.bmiHeader.biWidth = bm.bmWidth;
+ l_BitmapInfo.bmiHeader.biHeight = bm.bmHeight;
+ l_BitmapInfo.bmiHeader.biPlanes = bm.bmPlanes;
+ l_BitmapInfo.bmiHeader.biBitCount = bm.bmBitsPixel;
+ l_BitmapInfo.bmiHeader.biCompression = BI_RGB;
+
+ // create Buffer for Image
+ RGBQUAD * l_pRawBytes = new RGBQUAD[bm.bmWidth * bm.bmHeight];
+
+ HDC dc = ::GetDC(NULL);
+
+ if(dc)
+ {
+ // Get Pixel Data from Image
+ if(GetDIBits(dc, hbmp, 0, bm.bmHeight, l_pRawBytes, &l_BitmapInfo, DIB_RGB_COLORS))
+ {
+ RGBQUAD * lpArray = l_pRawBytes;
+ RGBQUAD * lpArrayEnd = l_pRawBytes + (bm.bmWidth * bm.bmHeight);
+
+ // check if Alpha Channel is realy valid (anny value not zero)
+ for( ;lpArray != lpArrayEnd ; ++lpArray )
+ {
+ // any alpha value not zero
+ if( lpArray->rgbReserved != 0 )
+ {
+ // must be vaid alph channel
+ lbAlphaValid = true;
+ break;
+ }
+ }
+ }
+ ::ReleaseDC(NULL, dc);
+ }
+ // free temporary Memory
+ delete [] l_pRawBytes;
+ }
+ }
+
+ return lbAlphaValid;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Bitmap resource constructor
+ * \param hbmp : bitmap resource handle
+ * \param hpal : (optional) palette, useful for 8bpp DC
+ * \param bTransparency : (optional) for 32bpp images only, imports trancparency
+ * \return true if everything is ok
+ * \author []; changes [brunom]
+ */
+bool CxImage::CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal, bool bTransparency)
+{
+ if (!Destroy())
+ return false;
+
+ if (hbmp) {
+ BITMAP bm;
+ // get informations about the bitmap
+ GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
+
+ // Transparency in HBITMAP
+ if(bTransparency && IsHBITMAPAlphaValid(hbmp))
+ {
+ bool l_bResult = true;
+
+ BITMAPINFO l_BitmapInfo;
+ l_BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ l_BitmapInfo.bmiHeader.biWidth = bm.bmWidth;
+ l_BitmapInfo.bmiHeader.biHeight = bm.bmHeight;
+ l_BitmapInfo.bmiHeader.biPlanes = bm.bmPlanes;
+ l_BitmapInfo.bmiHeader.biBitCount = bm.bmBitsPixel;
+ l_BitmapInfo.bmiHeader.biCompression = BI_RGB;
+
+ RGBQUAD *l_pRawBytes = new RGBQUAD[bm.bmWidth * bm.bmHeight];
+
+ HDC dc = ::GetDC(NULL);
+
+ if(dc)
+ {
+ if(GetDIBits(dc, hbmp, 0, bm.bmHeight, l_pRawBytes, &l_BitmapInfo, DIB_RGB_COLORS))
+ l_bResult = CreateFromArray((uint8_t*)l_pRawBytes, bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, bm.bmWidthBytes, false);
+ else
+ l_bResult = false;
+
+ ::ReleaseDC(NULL, dc);
+ }
+ else
+ l_bResult = false;
+
+ delete [] l_pRawBytes;
+
+ return l_bResult;
+ }
+ else
+ {
+ // create the image
+ if (!Create(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, 0))
+ return false;
+ // create a device context for the bitmap
+ HDC dc = ::GetDC(NULL);
+ if (!dc)
+ return false;
+
+ if (hpal){
+ SelectObject(dc,hpal); //the palette you should get from the user or have a stock one
+ RealizePalette(dc);
+ }
+
+ // copy the pixels
+ if (GetDIBits(dc, hbmp, 0, head.biHeight, info.pImage,
+ (LPBITMAPINFO)pDib, DIB_RGB_COLORS) == 0){ //replace &head with pDib <Wil Stark>
+ strcpy(info.szLastError,"GetDIBits failed");
+ ::ReleaseDC(NULL, dc);
+ return false;
+ }
+ ::ReleaseDC(NULL, dc);
+ return true;
+ }
+ }
+ return false;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * icon resource constructor
+ * \param hico : icon resource handle
+ * \param bTransparency : (optional) for 32bpp images only, imports trancparency
+ * \return true if everything is ok
+ * \author []; changes [Arlen Albert Keshabian], [brunom]
+ */
+#if !defined (_WIN32_WCE)
+bool CxImage::CreateFromHICON(HICON hico, bool bTransparency)
+{
+ if (!Destroy() || !hico)
+ return false;
+
+ bool l_bResult = true;
+
+ ICONINFO iinfo;
+ GetIconInfo(hico,&iinfo);
+
+ //BITMAP l_Bitmap;
+ //GetObject(iinfo.hbmColor, sizeof(BITMAP), &l_Bitmap);
+
+ l_bResult = CreateFromHBITMAP( iinfo.hbmColor, NULL, bTransparency );
+
+#if CXIMAGE_SUPPORT_ALPHA
+ if(l_bResult && ((!IsHBITMAPAlphaValid(iinfo.hbmColor)) || (!bTransparency)) )
+ {
+ CxImage mask;
+ mask.CreateFromHBITMAP(iinfo.hbmMask);
+ mask.GrayScale();
+ mask.Negative();
+ AlphaSet(mask);
+ }
+#endif
+
+ DeleteObject(iinfo.hbmColor); //<Sims>
+ DeleteObject(iinfo.hbmMask); //<Sims>
+
+ return l_bResult;
+}
+#endif //_WIN32_WCE
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::Draw(HDC hdc, const RECT& rect, RECT* pClipRect, bool bSmooth, bool bFlipY)
+{
+ return Draw(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pClipRect,bSmooth, bFlipY);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Draws the image in the specified device context, with support for alpha channel, alpha palette, transparency, opacity.
+ * \param hdc : destination device context
+ * \param x,y : (optional) offset
+ * \param cx,cy : (optional) size.
+ * - If cx or cy are not specified (or less than 0), the normal width or height will be used
+ * - If cx or cy are different than width or height, the image will be stretched
+ *
+ * \param pClipRect : limit the drawing operations inside a given rectangle in the output device context.
+ * \param bSmooth : activates a bilinear filter that will enhance the appearence for zommed pictures.
+ * Quite slow. Needs CXIMAGE_SUPPORT_INTERPOLATION.
+ * \param bFlipY : draws a mirror image along the y-axis
+ * \return true if everything is ok
+ */
+int32_t CxImage::Draw(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy, RECT* pClipRect, bool bSmooth, bool bFlipY)
+{
+ if((pDib==0)||(hdc==0)||(cx==0)||(cy==0)||(!info.bEnabled)) return 0;
+
+ if (cx < 0) cx = head.biWidth;
+ if (cy < 0) cy = head.biHeight;
+ bool bTransparent = info.nBkgndIndex >= 0;
+ bool bAlpha = pAlpha != 0;
+
+ //required for MM_ANISOTROPIC, MM_HIENGLISH, and similar modes [Greg Peatfield]
+ int32_t hdc_Restore = ::SaveDC(hdc);
+ if (!hdc_Restore)
+ return 0;
+
+#if !defined (_WIN32_WCE)
+ RECT mainbox; // (experimental)
+ if (pClipRect){
+ GetClipBox(hdc,&mainbox);
+ HRGN rgn = CreateRectRgnIndirect(pClipRect);
+ ExtSelectClipRgn(hdc,rgn,RGN_AND);
+ DeleteObject(rgn);
+ }
+#endif
+
+ //find the smallest area to paint
+ RECT clipbox,paintbox;
+ GetClipBox(hdc,&clipbox);
+
+ paintbox.top = min(clipbox.bottom,max(clipbox.top,y));
+ paintbox.left = min(clipbox.right,max(clipbox.left,x));
+ paintbox.right = max(clipbox.left,min(clipbox.right,x+cx));
+ paintbox.bottom = max(clipbox.top,min(clipbox.bottom,y+cy));
+
+ int32_t destw = paintbox.right - paintbox.left;
+ int32_t desth = paintbox.bottom - paintbox.top;
+
+ if (!(bTransparent || bAlpha || info.bAlphaPaletteEnabled)){
+ if (cx==head.biWidth && cy==head.biHeight){ //NORMAL
+#if !defined (_WIN32_WCE)
+ SetStretchBltMode(hdc,COLORONCOLOR);
+#endif
+ if (bFlipY){
+ StretchDIBits(hdc, x, y+cy-1,
+ cx, -cy, 0, 0, cx, cy,
+ info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS,SRCCOPY);
+ } else {
+ SetDIBitsToDevice(hdc, x, y, cx, cy, 0, 0, 0, cy,
+ info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS);
+ }
+ } else { //STRETCH
+ //pixel informations
+ RGBQUAD c={0,0,0,0};
+ //Preparing Bitmap Info
+ BITMAPINFO bmInfo;
+ memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
+ bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth=destw;
+ bmInfo.bmiHeader.biHeight=desth;
+ bmInfo.bmiHeader.biPlanes=1;
+ bmInfo.bmiHeader.biBitCount=24;
+ uint8_t *pbase; //points to the final dib
+ uint8_t *pdst; //current pixel from pbase
+ uint8_t *ppix; //current pixel from image
+ //get the background
+ HDC TmpDC=CreateCompatibleDC(hdc);
+ HBITMAP TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
+ HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
+
+ if (pbase){
+ int32_t xx,yy;
+ int32_t sx,sy;
+ float dx,dy;
+ uint8_t *psrc;
+
+ int32_t ew = ((((24 * destw) + 31) / 32) * 4);
+ int32_t ymax = paintbox.bottom;
+ int32_t xmin = paintbox.left;
+ float fx=(float)head.biWidth/(float)cx;
+ float fy=(float)head.biHeight/(float)cy;
+
+ for(yy=0;yy<desth;yy++){
+ dy = head.biHeight-(ymax-yy-y)*fy;
+ sy = max(0L,(int32_t)floor(dy));
+ psrc = info.pImage+sy*info.dwEffWidth;
+ if (bFlipY){
+ pdst = pbase+(desth-1-yy)*ew;
+ } else {
+ pdst = pbase+yy*ew;
+ }
+ for(xx=0;xx<destw;xx++){
+ dx = (xx+xmin-x)*fx;
+ sx = max(0L,(int32_t)floor(dx));
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bSmooth){
+ if (fx > 1 && fy > 1) {
+ c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ } else {
+ c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ }
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ if (head.biClrUsed){
+ c=GetPaletteColor(GetPixelIndex(sx,sy));
+ } else {
+ ppix = psrc + sx*3;
+ c.rgbBlue = *ppix++;
+ c.rgbGreen= *ppix++;
+ c.rgbRed = *ppix;
+ }
+ }
+ *pdst++=c.rgbBlue;
+ *pdst++=c.rgbGreen;
+ *pdst++=c.rgbRed;
+ }
+ }
+ }
+ //paint the image & cleanup
+ SetDIBitsToDevice(hdc,paintbox.left,paintbox.top,destw,desth,0,0,0,desth,pbase,&bmInfo,0);
+ DeleteObject(SelectObject(TmpDC,TmpObj));
+ DeleteDC(TmpDC);
+ }
+ } else { // draw image with transparent/alpha blending
+ //////////////////////////////////////////////////////////////////
+ //Alpha blend - Thanks to Florian Egel
+
+ //pixel informations
+ RGBQUAD c={0,0,0,0};
+ RGBQUAD ct = GetTransColor();
+ int32_t* pc = (int32_t*)&c;
+ int32_t* pct= (int32_t*)&ct;
+ int32_t cit = GetTransIndex();
+ int32_t ci = 0;
+
+ //Preparing Bitmap Info
+ BITMAPINFO bmInfo;
+ memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
+ bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth=destw;
+ bmInfo.bmiHeader.biHeight=desth;
+ bmInfo.bmiHeader.biPlanes=1;
+ bmInfo.bmiHeader.biBitCount=24;
+
+ uint8_t *pbase; //points to the final dib
+ uint8_t *pdst; //current pixel from pbase
+ uint8_t *ppix; //current pixel from image
+
+ //get the background
+ HDC TmpDC=CreateCompatibleDC(hdc);
+ HBITMAP TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
+ HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
+ BitBlt(TmpDC,0,0,destw,desth,hdc,paintbox.left,paintbox.top,SRCCOPY);
+
+ if (pbase){
+ int32_t xx,yy,alphaoffset,ix,iy;
+ uint8_t a,a1,*psrc;
+ int32_t ew = ((((24 * destw) + 31) / 32) * 4);
+ int32_t ymax = paintbox.bottom;
+ int32_t xmin = paintbox.left;
+
+ if (cx!=head.biWidth || cy!=head.biHeight){
+ //STRETCH
+ float fx=(float)head.biWidth/(float)cx;
+ float fy=(float)head.biHeight/(float)cy;
+ float dx,dy;
+ int32_t sx,sy;
+
+ for(yy=0;yy<desth;yy++){
+ dy = head.biHeight-(ymax-yy-y)*fy;
+ sy = max(0L,(int32_t)floor(dy));
+
+ alphaoffset = sy*head.biWidth;
+ if (bFlipY){
+ pdst = pbase+(desth-1-yy)*ew;
+ } else {
+ pdst = pbase + yy*ew;
+ }
+ psrc = info.pImage + sy*info.dwEffWidth;
+
+ for(xx=0;xx<destw;xx++){
+ dx = (xx+xmin-x)*fx;
+ sx = max(0L,(int32_t)floor(dx));
+
+ if (bAlpha) a=pAlpha[alphaoffset+sx]; else a=255;
+ a =(uint8_t)((a*(1+info.nAlphaMax))>>8);
+
+ if (head.biClrUsed){
+ ci = GetPixelIndex(sx,sy);
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bSmooth){
+ if (fx > 1 && fy > 1) {
+ c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ } else {
+ c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ }
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ c = GetPaletteColor(GetPixelIndex(sx,sy));
+ }
+ if (info.bAlphaPaletteEnabled){
+ a = (uint8_t)((a*(1+c.rgbReserved))>>8);
+ }
+ } else {
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bSmooth){
+ if (fx > 1 && fy > 1) {
+ c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ } else {
+ c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ }
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ ppix = psrc + sx*3;
+ c.rgbBlue = *ppix++;
+ c.rgbGreen= *ppix++;
+ c.rgbRed = *ppix;
+ }
+ }
+ //if (*pc!=*pct || !bTransparent){
+ //if ((head.biClrUsed && ci!=cit) || ((!head.biClrUsed||bSmooth) && *pc!=*pct) || !bTransparent){
+ if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent){
+ // DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
+ if (a == 0) { // Transparent, retain dest
+ pdst+=3;
+ } else if (a == 255) { // opaque, ignore dest
+ *pdst++= c.rgbBlue;
+ *pdst++= c.rgbGreen;
+ *pdst++= c.rgbRed;
+ } else { // semi transparent
+ a1=(uint8_t)~a;
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbBlue)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbGreen)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbRed)>>8);
+ }
+ } else {
+ pdst+=3;
+ }
+ }
+ }
+ } else {
+ //NORMAL
+ iy=head.biHeight-ymax+y;
+ for(yy=0;yy<desth;yy++,iy++){
+ alphaoffset=iy*head.biWidth;
+ ix=xmin-x;
+ if (bFlipY){
+ pdst = pbase+(desth-1-yy)*ew;
+ } else {
+ pdst = pbase+yy*ew;
+ }
+ ppix=info.pImage+iy*info.dwEffWidth+ix*3;
+ for(xx=0;xx<destw;xx++,ix++){
+
+ if (bAlpha) a=pAlpha[alphaoffset+ix]; else a=255;
+ a = (uint8_t)((a*(1+info.nAlphaMax))>>8);
+
+ if (head.biClrUsed){
+ ci = GetPixelIndex(ix,iy);
+ c = GetPaletteColor((uint8_t)ci);
+ if (info.bAlphaPaletteEnabled){
+ a = (uint8_t)((a*(1+c.rgbReserved))>>8);
+ }
+ } else {
+ c.rgbBlue = *ppix++;
+ c.rgbGreen= *ppix++;
+ c.rgbRed = *ppix++;
+ }
+
+ //if (*pc!=*pct || !bTransparent){
+ if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent){
+ // DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
+ if (a == 0) { // Transparent, retain dest
+ pdst+=3;
+ } else if (a == 255) { // opaque, ignore dest
+ *pdst++= c.rgbBlue;
+ *pdst++= c.rgbGreen;
+ *pdst++= c.rgbRed;
+ } else { // semi transparent
+ a1=(uint8_t)~a;
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbBlue)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbGreen)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbRed)>>8);
+ }
+ } else {
+ pdst+=3;
+ }
+ }
+ }
+ }
+ }
+ //paint the image & cleanup
+ SetDIBitsToDevice(hdc,paintbox.left,paintbox.top,destw,desth,0,0,0,desth,pbase,&bmInfo,0);
+ DeleteObject(SelectObject(TmpDC,TmpObj));
+ DeleteDC(TmpDC);
+ }
+
+#if !defined (_WIN32_WCE)
+ if (pClipRect){ // (experimental)
+ HRGN rgn = CreateRectRgnIndirect(&mainbox);
+ ExtSelectClipRgn(hdc,rgn,RGN_OR);
+ DeleteObject(rgn);
+ }
+#endif
+
+ ::RestoreDC(hdc,hdc_Restore);
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * renders the image into a HBITMAP handle
+ * \param hdc : destination device context
+ * \param x,y : (optional) offset
+ * \param cx,cy : (optional) size.
+ * - If cx or cy are not specified (or less than 0), the normal width or height will be used
+ * - If cx or cy are different than width or height, the image will be stretched
+ * \param pClipRect : limit the drawing operations inside a given rectangle in the output device context.
+ * \param bSmooth : activates a bilinear filter that will enhance the appearence for zommed pictures.
+ * Quite slow. Needs CXIMAGE_SUPPORT_INTERPOLATION.
+ * \return HBITMAP handle, NULL in case of error
+ * \sa MakeBitmap
+ */
+HBITMAP CxImage::Draw2HBITMAP(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy, RECT* pClipRect, bool bSmooth)
+{
+ if((pDib==0)||(hdc==0)||(cx==0)||(cy==0)||(!info.bEnabled)) return 0;
+
+ if (cx < 0) cx = head.biWidth;
+ if (cy < 0) cy = head.biHeight;
+ bool bTransparent = info.nBkgndIndex >= 0;
+ bool bAlpha = pAlpha != 0;
+
+ //required for MM_ANISOTROPIC, MM_HIENGLISH, and similar modes [Greg Peatfield]
+ int32_t hdc_Restore = ::SaveDC(hdc);
+ if (!hdc_Restore)
+ return 0;
+
+#if !defined (_WIN32_WCE)
+ RECT mainbox; // (experimental)
+ if (pClipRect){
+ GetClipBox(hdc,&mainbox);
+ HRGN rgn = CreateRectRgnIndirect(pClipRect);
+ ExtSelectClipRgn(hdc,rgn,RGN_AND);
+ DeleteObject(rgn);
+ }
+#endif
+
+ HBITMAP TmpBmp;
+
+ //find the smallest area to paint
+ RECT clipbox,paintbox;
+ GetClipBox(hdc,&clipbox);
+
+ paintbox.top = min(clipbox.bottom,max(clipbox.top,y));
+ paintbox.left = min(clipbox.right,max(clipbox.left,x));
+ paintbox.right = max(clipbox.left,min(clipbox.right,x+cx));
+ paintbox.bottom = max(clipbox.top,min(clipbox.bottom,y+cy));
+
+ int32_t destw = paintbox.right - paintbox.left;
+ int32_t desth = paintbox.bottom - paintbox.top;
+
+ if (!(bTransparent || bAlpha || info.bAlphaPaletteEnabled)){
+ if (cx==head.biWidth && cy==head.biHeight){ //NORMAL
+#if !defined (_WIN32_WCE)
+ SetStretchBltMode(hdc,COLORONCOLOR);
+#endif
+ SetDIBitsToDevice(hdc, x, y, cx, cy, 0, 0, 0, cy,
+ info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS);
+ } else { //STRETCH
+ //pixel informations
+ RGBQUAD c={0,0,0,0};
+ //Preparing Bitmap Info
+ BITMAPINFO bmInfo;
+ memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
+ bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth=destw;
+ bmInfo.bmiHeader.biHeight=desth;
+ bmInfo.bmiHeader.biPlanes=1;
+ bmInfo.bmiHeader.biBitCount=24;
+ uint8_t *pbase; //points to the final dib
+ uint8_t *pdst; //current pixel from pbase
+ uint8_t *ppix; //current pixel from image
+ //get the background
+ HDC TmpDC=CreateCompatibleDC(hdc);
+ TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
+ HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
+
+ if (pbase){
+ int32_t xx,yy;
+ int32_t sx,sy;
+ float dx,dy;
+ uint8_t *psrc;
+
+ int32_t ew = ((((24 * destw) + 31) / 32) * 4);
+ int32_t ymax = paintbox.bottom;
+ int32_t xmin = paintbox.left;
+ float fx=(float)head.biWidth/(float)cx;
+ float fy=(float)head.biHeight/(float)cy;
+
+ for(yy=0;yy<desth;yy++){
+ dy = head.biHeight-(ymax-yy-y)*fy;
+ sy = max(0L,(int32_t)floor(dy));
+ psrc = info.pImage+sy*info.dwEffWidth;
+ pdst = pbase+yy*ew;
+ for(xx=0;xx<destw;xx++){
+ dx = (xx+xmin-x)*fx;
+ sx = max(0L,(int32_t)floor(dx));
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bSmooth){
+ if (fx > 1 && fy > 1) {
+ c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ } else {
+ c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ }
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ if (head.biClrUsed){
+ c=GetPaletteColor(GetPixelIndex(sx,sy));
+ } else {
+ ppix = psrc + sx*3;
+ c.rgbBlue = *ppix++;
+ c.rgbGreen= *ppix++;
+ c.rgbRed = *ppix;
+ }
+ }
+ *pdst++=c.rgbBlue;
+ *pdst++=c.rgbGreen;
+ *pdst++=c.rgbRed;
+ }
+ }
+ }
+ //cleanup
+ SelectObject(TmpDC,TmpObj);
+ DeleteDC(TmpDC);
+ }
+ } else { // draw image with transparent/alpha blending
+ //////////////////////////////////////////////////////////////////
+ //Alpha blend - Thanks to Florian Egel
+
+ //pixel informations
+ RGBQUAD c={0,0,0,0};
+ RGBQUAD ct = GetTransColor();
+ int32_t* pc = (int32_t*)&c;
+ int32_t* pct= (int32_t*)&ct;
+ int32_t cit = GetTransIndex();
+ int32_t ci = 0;
+
+ //Preparing Bitmap Info
+ BITMAPINFO bmInfo;
+ memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
+ bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth=destw;
+ bmInfo.bmiHeader.biHeight=desth;
+ bmInfo.bmiHeader.biPlanes=1;
+ bmInfo.bmiHeader.biBitCount=24;
+
+ uint8_t *pbase; //points to the final dib
+ uint8_t *pdst; //current pixel from pbase
+ uint8_t *ppix; //current pixel from image
+
+ //get the background
+ HDC TmpDC=CreateCompatibleDC(hdc);
+ TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
+ HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
+ BitBlt(TmpDC,0,0,destw,desth,hdc,paintbox.left,paintbox.top,SRCCOPY);
+
+ if (pbase){
+ int32_t xx,yy,alphaoffset,ix,iy;
+ uint8_t a,a1,*psrc;
+ int32_t ew = ((((24 * destw) + 31) / 32) * 4);
+ int32_t ymax = paintbox.bottom;
+ int32_t xmin = paintbox.left;
+
+ if (cx!=head.biWidth || cy!=head.biHeight){
+ //STRETCH
+ float fx=(float)head.biWidth/(float)cx;
+ float fy=(float)head.biHeight/(float)cy;
+ float dx,dy;
+ int32_t sx,sy;
+
+ for(yy=0;yy<desth;yy++){
+ dy = head.biHeight-(ymax-yy-y)*fy;
+ sy = max(0L,(int32_t)floor(dy));
+
+ alphaoffset = sy*head.biWidth;
+ pdst = pbase + yy*ew;
+ psrc = info.pImage + sy*info.dwEffWidth;
+
+ for(xx=0;xx<destw;xx++){
+ dx = (xx+xmin-x)*fx;
+ sx = max(0L,(int32_t)floor(dx));
+
+ if (bAlpha) a=pAlpha[alphaoffset+sx]; else a=255;
+ a =(uint8_t)((a*(1+info.nAlphaMax))>>8);
+
+ if (head.biClrUsed){
+ ci = GetPixelIndex(sx,sy);
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bSmooth){
+ if (fx > 1 && fy > 1) {
+ c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ } else {
+ c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ }
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ c = GetPaletteColor(GetPixelIndex(sx,sy));
+ }
+ if (info.bAlphaPaletteEnabled){
+ a = (uint8_t)((a*(1+c.rgbReserved))>>8);
+ }
+ } else {
+#if CXIMAGE_SUPPORT_INTERPOLATION
+ if (bSmooth){
+ if (fx > 1 && fy > 1) {
+ c = GetAreaColorInterpolated(dx - 0.5f, dy - 0.5f, fx, fy, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ } else {
+ c = GetPixelColorInterpolated(dx - 0.5f, dy - 0.5f, CxImage::IM_BILINEAR, CxImage::OM_REPEAT);
+ }
+ } else
+#endif //CXIMAGE_SUPPORT_INTERPOLATION
+ {
+ ppix = psrc + sx*3;
+ c.rgbBlue = *ppix++;
+ c.rgbGreen= *ppix++;
+ c.rgbRed = *ppix;
+ }
+ }
+ //if (*pc!=*pct || !bTransparent){
+ //if ((head.biClrUsed && ci!=cit) || ((!head.biClrUsed||bSmooth) && *pc!=*pct) || !bTransparent){
+ if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent){
+ // DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
+ if (a == 0) { // Transparent, retain dest
+ pdst+=3;
+ } else if (a == 255) { // opaque, ignore dest
+ *pdst++= c.rgbBlue;
+ *pdst++= c.rgbGreen;
+ *pdst++= c.rgbRed;
+ } else { // semi transparent
+ a1=(uint8_t)~a;
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbBlue)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbGreen)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbRed)>>8);
+ }
+ } else {
+ pdst+=3;
+ }
+ }
+ }
+ } else {
+ //NORMAL
+ iy=head.biHeight-ymax+y;
+ for(yy=0;yy<desth;yy++,iy++){
+ alphaoffset=iy*head.biWidth;
+ ix=xmin-x;
+ pdst=pbase+yy*ew;
+ ppix=info.pImage+iy*info.dwEffWidth+ix*3;
+ for(xx=0;xx<destw;xx++,ix++){
+
+ if (bAlpha) a=pAlpha[alphaoffset+ix]; else a=255;
+ a = (uint8_t)((a*(1+info.nAlphaMax))>>8);
+
+ if (head.biClrUsed){
+ ci = GetPixelIndex(ix,iy);
+ c = GetPaletteColor((uint8_t)ci);
+ if (info.bAlphaPaletteEnabled){
+ a = (uint8_t)((a*(1+c.rgbReserved))>>8);
+ }
+ } else {
+ c.rgbBlue = *ppix++;
+ c.rgbGreen= *ppix++;
+ c.rgbRed = *ppix++;
+ }
+
+ //if (*pc!=*pct || !bTransparent){
+ if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent){
+ // DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
+ if (a == 0) { // Transparent, retain dest
+ pdst+=3;
+ } else if (a == 255) { // opaque, ignore dest
+ *pdst++= c.rgbBlue;
+ *pdst++= c.rgbGreen;
+ *pdst++= c.rgbRed;
+ } else { // semi transparent
+ a1=(uint8_t)~a;
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbBlue)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbGreen)>>8);
+ *pdst++=(uint8_t)((*pdst * a1 + a * c.rgbRed)>>8);
+ }
+ } else {
+ pdst+=3;
+ }
+ }
+ }
+ }
+ }
+ //cleanup
+ SelectObject(TmpDC,TmpObj);
+ DeleteDC(TmpDC);
+ }
+
+#if !defined (_WIN32_WCE)
+ if (pClipRect){ // (experimental)
+ HRGN rgn = CreateRectRgnIndirect(&mainbox);
+ ExtSelectClipRgn(hdc,rgn,RGN_OR);
+ DeleteObject(rgn);
+ }
+#endif
+
+ ::RestoreDC(hdc,hdc_Restore);
+ return TmpBmp;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::Draw2(HDC hdc, const RECT& rect)
+{
+ return Draw2(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Draws (stretch) the image with single transparency support
+ * \param hdc : destination device context
+ * \param x,y : (optional) offset
+ * \param cx,cy : (optional) size.
+ * - If cx or cy are not specified (or less than 0), the normal width or height will be used
+ * - If cx or cy are different than width or height, the image will be stretched
+ *
+ * \return true if everything is ok
+ */
+int32_t CxImage::Draw2(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy)
+{
+ if((pDib==0)||(hdc==0)||(cx==0)||(cy==0)||(!info.bEnabled)) return 0;
+ if (cx < 0) cx = head.biWidth;
+ if (cy < 0) cy = head.biHeight;
+ bool bTransparent = (info.nBkgndIndex >= 0);
+
+ //required for MM_ANISOTROPIC, MM_HIENGLISH, and similar modes [Greg Peatfield]
+ int32_t hdc_Restore = ::SaveDC(hdc);
+ if (!hdc_Restore)
+ return 0;
+
+ if (!bTransparent){
+#if !defined (_WIN32_WCE)
+ SetStretchBltMode(hdc,COLORONCOLOR);
+#endif
+ StretchDIBits(hdc, x, y, cx, cy, 0, 0, head.biWidth, head.biHeight,
+ info.pImage,(BITMAPINFO*)pDib, DIB_RGB_COLORS,SRCCOPY);
+ } else {
+ // draw image with transparent background
+ const int32_t safe = 0; // or else GDI fails in the following - sometimes
+ RECT rcDst = {x+safe, y+safe, x+cx, y+cy};
+ if (RectVisible(hdc, &rcDst)){
+ /////////////////////////////////////////////////////////////////
+ // True Mask Method - Thanks to Paul Reynolds and Ron Gery
+ int32_t nWidth = head.biWidth;
+ int32_t nHeight = head.biHeight;
+ // Create two memory dcs for the image and the mask
+ HDC dcImage=CreateCompatibleDC(hdc);
+ HDC dcTrans=CreateCompatibleDC(hdc);
+ // Select the image into the appropriate dc
+ HBITMAP bm = CreateCompatibleBitmap(hdc, nWidth, nHeight);
+ HBITMAP pOldBitmapImage = (HBITMAP)SelectObject(dcImage,bm);
+#if !defined (_WIN32_WCE)
+ SetStretchBltMode(dcImage,COLORONCOLOR);
+#endif
+ StretchDIBits(dcImage, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
+ info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS,SRCCOPY);
+
+ // Create the mask bitmap
+ HBITMAP bitmapTrans = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
+ // Select the mask bitmap into the appropriate dc
+ HBITMAP pOldBitmapTrans = (HBITMAP)SelectObject(dcTrans, bitmapTrans);
+ // Build mask based on transparent colour
+ RGBQUAD rgbBG;
+ if (head.biBitCount<24) rgbBG = GetPaletteColor((uint8_t)info.nBkgndIndex);
+ else rgbBG = info.nBkgndColor;
+ COLORREF crColour = RGB(rgbBG.rgbRed, rgbBG.rgbGreen, rgbBG.rgbBlue);
+ COLORREF crOldBack = SetBkColor(dcImage,crColour);
+ BitBlt(dcTrans,0, 0, nWidth, nHeight, dcImage, 0, 0, SRCCOPY);
+
+ // Do the work - True Mask method - cool if not actual display
+ StretchBlt(hdc,x, y,cx,cy, dcImage, 0, 0, nWidth, nHeight, SRCINVERT);
+ StretchBlt(hdc,x, y,cx,cy, dcTrans, 0, 0, nWidth, nHeight, SRCAND);
+ StretchBlt(hdc,x, y,cx,cy, dcImage, 0, 0, nWidth, nHeight, SRCINVERT);
+
+ // Restore settings
+ SelectObject(dcImage,pOldBitmapImage);
+ SelectObject(dcTrans,pOldBitmapTrans);
+ SetBkColor(hdc,crOldBack);
+ DeleteObject( bitmapTrans ); // RG 29/01/2002
+ DeleteDC(dcImage);
+ DeleteDC(dcTrans);
+ DeleteObject(bm);
+ }
+ }
+ ::RestoreDC(hdc,hdc_Restore);
+ return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::Stretch(HDC hdc, const RECT& rect, uint32_t dwRop)
+{
+ return Stretch(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, dwRop);
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Stretch the image. Obsolete: use Draw() or Draw2()
+ * \param hdc : destination device context
+ * \param xoffset,yoffset : (optional) offset
+ * \param xsize,ysize : size.
+ * \param dwRop : raster operation code (see BitBlt documentation)
+ * \return true if everything is ok
+ */
+int32_t CxImage::Stretch(HDC hdc, int32_t xoffset, int32_t yoffset, int32_t xsize, int32_t ysize, uint32_t dwRop)
+{
+ if((pDib)&&(hdc)) {
+ //palette must be correctly filled
+#if !defined (_WIN32_WCE)
+ SetStretchBltMode(hdc,COLORONCOLOR);
+#endif
+ StretchDIBits(hdc, xoffset, yoffset,
+ xsize, ysize, 0, 0, head.biWidth, head.biHeight,
+ info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS,dwRop);
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+/**
+ * Tiles the device context in the specified rectangle with the image.
+ * \param hdc : destination device context
+ * \param rc : tiled rectangle in the output device context
+ * \return true if everything is ok
+ */
+int32_t CxImage::Tile(HDC hdc, RECT *rc)
+{
+ if((pDib)&&(hdc)&&(rc)) {
+ int32_t w = rc->right - rc->left;
+ int32_t h = rc->bottom - rc->top;
+ int32_t x,y,z;
+ int32_t bx=head.biWidth;
+ int32_t by=head.biHeight;
+ for (y = 0 ; y < h ; y += by){
+ if ((y+by)>h) by=h-y;
+ z=bx;
+ for (x = 0 ; x < w ; x += z){
+ if ((x+z)>w) z=w-x;
+ RECT r = {rc->left + x,rc->top + y,rc->left + x + z,rc->top + y + by};
+ Draw(hdc,rc->left + x, rc->top + y,-1,-1,&r);
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+////////////////////////////////////////////////////////////////////////////////
+// For UNICODE support: char -> TCHAR
+int32_t CxImage::DrawString(HDC hdc, int32_t x, int32_t y, const TCHAR* text, RGBQUAD color, const TCHAR* font, int32_t lSize, int32_t lWeight, uint8_t bItalic, uint8_t bUnderline, bool bSetAlpha)
+//int32_t CxImage::DrawString(HDC hdc, int32_t x, int32_t y, const char* text, RGBQUAD color, const char* font, int32_t lSize, int32_t lWeight, uint8_t bItalic, uint8_t bUnderline, bool bSetAlpha)
+{
+ if (IsValid()){
+ //get the background
+ HDC pDC;
+ if (hdc) pDC=hdc; else pDC = ::GetDC(0);
+ if (pDC==NULL) return 0;
+ HDC TmpDC=CreateCompatibleDC(pDC);
+ if (hdc==NULL) ::ReleaseDC(0, pDC);
+ if (TmpDC==NULL) return 0;
+ //choose the font
+ HFONT m_Font;
+ LOGFONT* m_pLF;
+ m_pLF=(LOGFONT*)calloc(1,sizeof(LOGFONT));
+ _tcsncpy(m_pLF->lfFaceName,font,31); // For UNICODE support
+ //strncpy(m_pLF->lfFaceName,font,31);
+ m_pLF->lfHeight=lSize;
+ m_pLF->lfWeight=lWeight;
+ m_pLF->lfItalic=bItalic;
+ m_pLF->lfUnderline=bUnderline;
+ m_Font=CreateFontIndirect(m_pLF);
+ //select the font in the dc
+ HFONT pOldFont=NULL;
+ if (m_Font)
+ pOldFont = (HFONT)SelectObject(TmpDC,m_Font);
+ else
+ pOldFont = (HFONT)SelectObject(TmpDC,GetStockObject(DEFAULT_GUI_FONT));
+
+ //Set text color
+ SetTextColor(TmpDC,RGB(255,255,255));
+ SetBkColor(TmpDC,RGB(0,0,0));
+ //draw the text
+ SetBkMode(TmpDC,OPAQUE);
+ //Set text position;
+ RECT pos = {0,0,0,0};
+ //int32_t len = (int32_t)strlen(text);
+ int32_t len = (int32_t)_tcslen(text); // For UNICODE support
+ ::DrawText(TmpDC,text,len,&pos,DT_CALCRECT);
+ pos.right+=pos.bottom; //for italics
+
+ //Preparing Bitmap Info
+ int32_t width=pos.right;
+ int32_t height=pos.bottom;
+ BITMAPINFO bmInfo;
+ memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
+ bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth=width;
+ bmInfo.bmiHeader.biHeight=height;
+ bmInfo.bmiHeader.biPlanes=1;
+ bmInfo.bmiHeader.biBitCount=24;
+ uint8_t *pbase; //points to the final dib
+
+ HBITMAP TmpBmp=CreateDIBSection(TmpDC,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
+ HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
+ memset(pbase,0,height*((((24 * width) + 31) / 32) * 4));
+
+ ::DrawText(TmpDC,text,len,&pos,0);
+
+ CxImage itext;
+ itext.CreateFromHBITMAP(TmpBmp);
+
+ y=head.biHeight-y-1;
+ for (int32_t ix=0;ix<width;ix++){
+ for (int32_t iy=0;iy<height;iy++){
+ if (itext.GetPixelColor(ix,iy).rgbBlue) SetPixelColor(x+ix,y+iy,color,bSetAlpha);
+ }
+ }
+
+ //cleanup
+ if (pOldFont) SelectObject(TmpDC,pOldFont);
+ DeleteObject(m_Font);
+ free(m_pLF);
+ DeleteObject(SelectObject(TmpDC,TmpObj));
+ DeleteDC(TmpDC);
+ }
+
+ return 1;
+}
+////////////////////////////////////////////////////////////////////////////////
+// <VATI>
+int32_t CxImage::DrawStringEx(HDC hdc, int32_t x, int32_t y, CXTEXTINFO *pTextType, bool bSetAlpha )
+{
+ if (!IsValid())
+ return -1;
+
+ //get the background
+ HDC pDC;
+ if (hdc) pDC=hdc; else pDC = ::GetDC(0);
+ if (pDC==NULL) return 0;
+ HDC TmpDC=CreateCompatibleDC(pDC);
+ if (hdc==NULL) ::ReleaseDC(0, pDC);
+ if (TmpDC==NULL) return 0;
+
+ //choose the font
+ HFONT m_Font;
+ m_Font=CreateFontIndirect( &pTextType->lfont );
+
+ // get colors in RGBQUAD
+ RGBQUAD p_forecolor = RGBtoRGBQUAD(pTextType->fcolor);
+ RGBQUAD p_backcolor = RGBtoRGBQUAD(pTextType->bcolor);
+
+ // check alignment and re-set default if necessary
+ if ( pTextType->align != DT_CENTER &&
+ pTextType->align != DT_LEFT &&
+ pTextType->align != DT_RIGHT )
+ pTextType->align = DT_CENTER;
+
+ // check rounding radius and re-set default if necessary
+ if ( pTextType->b_round > 50 )
+ pTextType->b_round = 10;
+
+ // check opacity and re-set default if necessary
+ if ( pTextType->b_opacity > 1. || pTextType->b_opacity < .0 )
+ pTextType->b_opacity = 0.;
+
+ //select the font in the dc
+ HFONT pOldFont=NULL;
+ if (m_Font)
+ pOldFont = (HFONT)SelectObject(TmpDC,m_Font);
+ else
+ pOldFont = (HFONT)SelectObject(TmpDC,GetStockObject(DEFAULT_GUI_FONT));
+
+ //Set text color
+ SetTextColor(TmpDC,RGB(255,255,255));
+ SetBkColor(TmpDC,RGB(0,0,0));
+ SetBkMode(TmpDC,OPAQUE);
+ //Set text position;
+ RECT pos = {0,0,0,0};
+
+ // get text length and number of lines
+ int32_t i=0, numlines=1, len=(int32_t)_tcsclen(pTextType->text);
+ while (i<len)
+ {
+ if ( pTextType->text[i++]==13 )
+ numlines++;
+ }
+
+ ::DrawText(TmpDC, pTextType->text, len, &pos, /*DT_EDITCONTROL|DT_EXTERNALLEADING|*/DT_NOPREFIX | DT_CALCRECT );
+
+ // increase only if it's really italics, and only one line height
+ if ( pTextType->lfont.lfItalic )
+ pos.right += pos.bottom/2/numlines;
+
+ // background frame and rounding radius
+ int32_t frame = 0, roundR = 0;
+ if ( pTextType->opaque )
+ {
+ roundR= (int32_t)(pos.bottom/numlines * pTextType->b_round / 100 ) ;
+ frame = (int32_t)(/*3.5 + */0.29289*roundR ) ;
+ pos.right += pos.bottom/numlines/3 ; // JUST FOR BEAUTY
+ }
+
+ //Preparing Bitmap Info
+ int32_t width=pos.right +frame*2;
+ int32_t height=pos.bottom +frame*2;
+ BITMAPINFO bmInfo;
+ memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
+ bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmInfo.bmiHeader.biWidth=width;
+ bmInfo.bmiHeader.biHeight=height;
+ bmInfo.bmiHeader.biPlanes=1;
+ bmInfo.bmiHeader.biBitCount=24;
+ uint8_t *pbase; //points to the final dib
+
+ HBITMAP TmpBmp=CreateDIBSection(TmpDC,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
+ HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
+ memset(pbase,0,height*((((24 * width) + 31) / 32) * 4));
+
+ ::DrawText(TmpDC,pTextType->text,len, &pos, /*DT_EDITCONTROL|DT_EXTERNALLEADING|*/DT_NOPREFIX| pTextType->align );
+
+ CxImage itext;
+ itext.CreateFromHBITMAP(TmpBmp);
+ y=head.biHeight-y-1;
+
+ itext.Negative();
+
+#if CXIMAGE_SUPPORT_DSP
+ if (pTextType->smooth==FALSE){
+ itext.Threshold(128);
+ } else {
+ //itext.TextBlur();
+ }
+#endif
+
+ //move the insertion point according to alignment type
+ // DT_CENTER: cursor points to the center of text rectangle
+ // DT_RIGHT: cursor points to right side end of text rectangle
+ // DT_LEFT: cursor points to left end of text rectangle
+ if ( pTextType->align == DT_CENTER )
+ x -= width/2;
+ else if ( pTextType->align == DT_RIGHT )
+ x -= width;
+ if (x<0) x=0;
+
+ //draw the background first, if it exists
+ int32_t ix,iy;
+ if ( pTextType->opaque )
+ {
+ int32_t ixf=0;
+ for (ix=0;ix<width;ix++)
+ {
+ if ( ix<=roundR )
+ ixf = (int32_t)(.5+roundR-sqrt((float)(roundR*roundR-(ix-roundR)*(ix-roundR))));
+ else if ( ix>=width-roundR-1 )
+ ixf = (int32_t)(.5+roundR-sqrt((float)(roundR*roundR-(width-1-ix-roundR)*(width-1-ix-roundR))));
+ else
+ ixf=0;
+
+ for (iy=0;iy<height;iy++)
+ {
+ if ( (ix<=roundR && ( iy > height-ixf-1 || iy < ixf )) ||
+ (ix>=width-roundR-1 && ( iy > height-ixf-1 || iy < ixf )) )
+ continue;
+ else
+ if ( pTextType->b_opacity > 0.0 && pTextType->b_opacity < 1.0 )
+ {
+ RGBQUAD bcolor, pcolor;
+ // calculate a transition color from original image to background color:
+ pcolor = GetPixelColor(x+ix,y+iy);
+ bcolor.rgbBlue = (uint8_t)(pTextType->b_opacity * pcolor.rgbBlue + (1.0-pTextType->b_opacity) * p_backcolor.rgbBlue );
+ bcolor.rgbRed = (uint8_t)(pTextType->b_opacity * pcolor.rgbRed + (1.0-pTextType->b_opacity) * p_backcolor.rgbRed ) ;
+ bcolor.rgbGreen = (uint8_t)(pTextType->b_opacity * pcolor.rgbGreen + (1.0-pTextType->b_opacity) * p_backcolor.rgbGreen ) ;
+ bcolor.rgbReserved = 0;
+ SetPixelColor(x+ix,y+iy,bcolor,bSetAlpha);
+ }
+ else
+ SetPixelColor(x+ix,y+iy,p_backcolor,bSetAlpha);
+ }
+ }
+ }
+
+ // draw the text itself
+ for (ix=0;ix<width;ix++)
+ {
+ for (iy=0;iy<height;iy++)
+ {
+ RGBQUAD pcolor = GetPixelColor(x+ix,y+iy);
+ RGBQUAD tcolor = itext.GetPixelColor(ix,iy);
+ if (tcolor.rgbBlue!=255){
+ float a = tcolor.rgbBlue/255.0f;
+ pcolor.rgbBlue = (uint8_t)(a * (pcolor.rgbBlue - p_forecolor.rgbBlue) + p_forecolor.rgbBlue );
+ pcolor.rgbRed = (uint8_t)(a * (pcolor.rgbRed - p_forecolor.rgbRed) + p_forecolor.rgbRed ) ;
+ pcolor.rgbGreen = (uint8_t)(a * (pcolor.rgbGreen - p_forecolor.rgbGreen) + p_forecolor.rgbGreen );
+ pcolor.rgbReserved = 0;
+ SetPixelColor(x+ix+frame,y+iy-frame,pcolor,bSetAlpha);
+ //SetPixelColor(x+ix+frame,y+iy-frame,p_forecolor,bSetAlpha);
+ }
+ }
+ }
+
+ //cleanup
+ if (pOldFont) SelectObject(TmpDC,pOldFont);
+ DeleteObject(m_Font);
+ DeleteObject(SelectObject(TmpDC,TmpObj));
+ DeleteDC(TmpDC);
+ return 1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CxImage::InitTextInfo( CXTEXTINFO *txt )
+{
+
+ memset( txt, 0, sizeof(CXTEXTINFO));
+
+ // LOGFONT defaults
+ txt->lfont.lfHeight = -36;
+ txt->lfont.lfCharSet = EASTEUROPE_CHARSET; // just for Central-European users
+ txt->lfont.lfWeight = FW_NORMAL;
+ txt->lfont.lfWidth = 0;
+ txt->lfont.lfEscapement = 0;
+ txt->lfont.lfOrientation = 0;
+ txt->lfont.lfItalic = FALSE;
+ txt->lfont.lfUnderline = FALSE;
+ txt->lfont.lfStrikeOut = FALSE;
+ txt->lfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ txt->lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ txt->lfont.lfQuality = PROOF_QUALITY;
+ txt->lfont.lfPitchAndFamily= DEFAULT_PITCH | FF_DONTCARE ;
+ _stprintf( txt->lfont.lfFaceName, _T("Arial")); //use TCHAR mappings <Cesar M>
+
+ // initial colors
+ txt->fcolor = RGB( 255,255,160 ); // default foreground: light goldyellow
+ txt->bcolor = RGB( 0, 80,160 ); // default background: light blue
+
+ // background
+ txt->opaque = TRUE; // text has a non-transparent background;
+ txt->smooth = TRUE;
+ txt->b_opacity = 0.0; // default: opaque background
+ txt->b_outline = 0; // default: no outline (OUTLINE NOT IMPLEMENTED AT THIS TIME)
+ txt->b_round = 20; // default: rounding radius is 20% of the rectangle height
+ // the text
+ _stprintf( txt->text, _T("Sample Text 01234õû")); // text use TCHAR mappings <Cesar M>
+ txt->align = DT_CENTER;
+ return;
+}
+
+#if CXIMAGE_SUPPORT_LAYERS
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::LayerDrawAll(HDC hdc, const RECT& rect, RECT* pClipRect, bool bSmooth)
+{
+ return LayerDrawAll(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, pClipRect,bSmooth);
+}
+////////////////////////////////////////////////////////////////////////////////
+int32_t CxImage::LayerDrawAll(HDC hdc, int32_t x, int32_t y, int32_t cx, int32_t cy, RECT* pClipRect, bool bSmooth)
+{
+ int32_t n=0;
+ CxImage* pLayer;
+ while(pLayer=GetLayer(n++)){
+ if (pLayer->Draw(hdc,x+pLayer->info.xOffset,y+pLayer->info.yOffset,cx,cy,pClipRect,bSmooth)==0)
+ return 0;
+ if (pLayer->LayerDrawAll(hdc,x+pLayer->info.xOffset,y+pLayer->info.yOffset,cx,cy,pClipRect,bSmooth)==0)
+ return 0;
+ }
+ return 1;
+}
+#endif //CXIMAGE_SUPPORT_LAYERS
+
+////////////////////////////////////////////////////////////////////////////////
+#endif //CXIMAGE_SUPPORT_WINDOWS
+////////////////////////////////////////////////////////////////////////////////
diff --git a/archive/hge/CxImage/xiofile.h b/archive/hge/CxImage/xiofile.h new file mode 100644 index 0000000..e05811e --- /dev/null +++ b/archive/hge/CxImage/xiofile.h @@ -0,0 +1,125 @@ +#if !defined(__xiofile_h)
+#define __xiofile_h
+
+#include "xfile.h"
+//#include <TCHAR.h>
+
+class DLL_EXP CxIOFile : public CxFile
+ {
+public:
+ CxIOFile(FILE* fp = NULL)
+ {
+ m_fp = fp;
+ m_bCloseFile = (bool)(fp==0);
+ }
+
+ ~CxIOFile()
+ {
+ Close();
+ }
+//////////////////////////////////////////////////////////
+ bool Open(const TCHAR * filename, const TCHAR * mode)
+ {
+ if (m_fp) return false; // Can't re-open without closing first
+
+ m_fp = fopen(filename, mode);
+ if (!m_fp) return false;
+
+ m_bCloseFile = true;
+
+ return true;
+ }
+//////////////////////////////////////////////////////////
+ virtual bool Close()
+ {
+ int32_t iErr = 0;
+ if ( (m_fp) && (m_bCloseFile) ){
+ iErr = fclose(m_fp);
+ m_fp = NULL;
+ }
+ return (bool)(iErr==0);
+ }
+//////////////////////////////////////////////////////////
+ virtual size_t Read(void *buffer, size_t size, size_t count)
+ {
+ if (!m_fp) return 0;
+ return fread(buffer, size, count, m_fp);
+ }
+//////////////////////////////////////////////////////////
+ virtual size_t Write(const void *buffer, size_t size, size_t count)
+ {
+ if (!m_fp) return 0;
+ return fwrite(buffer, size, count, m_fp);
+ }
+//////////////////////////////////////////////////////////
+ virtual bool Seek(int32_t offset, int32_t origin)
+ {
+ if (!m_fp) return false;
+ return (bool)(fseek(m_fp, offset, origin) == 0);
+ }
+//////////////////////////////////////////////////////////
+ virtual int32_t Tell()
+ {
+ if (!m_fp) return 0;
+ return ftell(m_fp);
+ }
+//////////////////////////////////////////////////////////
+ virtual int32_t Size()
+ {
+ if (!m_fp) return -1;
+ int32_t pos,size;
+ pos = ftell(m_fp);
+ fseek(m_fp, 0, SEEK_END);
+ size = ftell(m_fp);
+ fseek(m_fp, pos,SEEK_SET);
+ return size;
+ }
+//////////////////////////////////////////////////////////
+ virtual bool Flush()
+ {
+ if (!m_fp) return false;
+ return (bool)(fflush(m_fp) == 0);
+ }
+//////////////////////////////////////////////////////////
+ virtual bool Eof()
+ {
+ if (!m_fp) return true;
+ return (bool)(feof(m_fp) != 0);
+ }
+//////////////////////////////////////////////////////////
+ virtual int32_t Error()
+ {
+ if (!m_fp) return -1;
+ return ferror(m_fp);
+ }
+//////////////////////////////////////////////////////////
+ virtual bool PutC(uint8_t c)
+ {
+ if (!m_fp) return false;
+ return (bool)(fputc(c, m_fp) == c);
+ }
+//////////////////////////////////////////////////////////
+ virtual int32_t GetC()
+ {
+ if (!m_fp) return EOF;
+ return getc(m_fp);
+ }
+//////////////////////////////////////////////////////////
+ virtual char * GetS(char *string, int32_t n)
+ {
+ if (!m_fp) return NULL;
+ return fgets(string,n,m_fp);
+ }
+//////////////////////////////////////////////////////////
+ virtual int32_t Scanf(const char *format, void* output)
+ {
+ if (!m_fp) return EOF;
+ return fscanf(m_fp, format, output);
+ }
+//////////////////////////////////////////////////////////
+protected:
+ FILE *m_fp;
+ bool m_bCloseFile;
+ };
+
+#endif
diff --git a/archive/hge/CxImage/xmemfile.cpp b/archive/hge/CxImage/xmemfile.cpp new file mode 100644 index 0000000..f235899 --- /dev/null +++ b/archive/hge/CxImage/xmemfile.cpp @@ -0,0 +1,213 @@ +#include "xmemfile.h"
+
+//////////////////////////////////////////////////////////
+CxMemFile::CxMemFile(uint8_t* pBuffer, uint32_t size)
+{
+ m_pBuffer = pBuffer;
+ m_Position = 0;
+ m_Size = m_Edge = size;
+ m_bFreeOnClose = (bool)(pBuffer==0);
+ m_bEOF = false;
+}
+//////////////////////////////////////////////////////////
+CxMemFile::~CxMemFile()
+{
+ Close();
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::Close()
+{
+ if ( (m_pBuffer) && (m_bFreeOnClose) ){
+ free(m_pBuffer);
+ m_pBuffer = NULL;
+ m_Size = 0;
+ }
+ return true;
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::Open()
+{
+ if (m_pBuffer) return false; // Can't re-open without closing first
+
+ m_Position = m_Size = m_Edge = 0;
+ m_pBuffer=(uint8_t*)malloc(1);
+ m_bFreeOnClose = true;
+
+ return (m_pBuffer!=0);
+}
+//////////////////////////////////////////////////////////
+uint8_t* CxMemFile::GetBuffer(bool bDetachBuffer)
+{
+ //can only detach, avoid inadvertantly attaching to
+ // memory that may not be ours [Jason De Arte]
+ if( bDetachBuffer )
+ m_bFreeOnClose = false;
+ return m_pBuffer;
+}
+//////////////////////////////////////////////////////////
+size_t CxMemFile::Read(void *buffer, size_t size, size_t count)
+{
+ if (buffer==NULL) return 0;
+
+ if (m_pBuffer==NULL) return 0;
+ if (m_Position >= (int32_t)m_Size){
+ m_bEOF = true;
+ return 0;
+ }
+
+ int32_t nCount = (int32_t)(count*size);
+ if (nCount == 0) return 0;
+
+ int32_t nRead;
+ if (m_Position + nCount > (int32_t)m_Size){
+ m_bEOF = true;
+ nRead = (m_Size - m_Position);
+ } else
+ nRead = nCount;
+
+ memcpy(buffer, m_pBuffer + m_Position, nRead);
+ m_Position += nRead;
+
+ return (size_t)(nRead/size);
+}
+//////////////////////////////////////////////////////////
+size_t CxMemFile::Write(const void *buffer, size_t size, size_t count)
+{
+ m_bEOF = false;
+ if (m_pBuffer==NULL) return 0;
+ if (buffer==NULL) return 0;
+
+ int32_t nCount = (int32_t)(count*size);
+ if (nCount == 0) return 0;
+
+ if (m_Position + nCount > m_Edge){
+ if (!Alloc(m_Position + nCount)){
+ return false;
+ }
+ }
+
+ memcpy(m_pBuffer + m_Position, buffer, nCount);
+
+ m_Position += nCount;
+
+ if (m_Position > (int32_t)m_Size) m_Size = m_Position;
+
+ return count;
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::Seek(int32_t offset, int32_t origin)
+{
+ m_bEOF = false;
+ if (m_pBuffer==NULL) return false;
+ int32_t lNewPos = m_Position;
+
+ if (origin == SEEK_SET) lNewPos = offset;
+ else if (origin == SEEK_CUR) lNewPos += offset;
+ else if (origin == SEEK_END) lNewPos = m_Size + offset;
+ else return false;
+
+ if (lNewPos < 0) lNewPos = 0;
+
+ m_Position = lNewPos;
+ return true;
+}
+//////////////////////////////////////////////////////////
+int32_t CxMemFile::Tell()
+{
+ if (m_pBuffer==NULL) return -1;
+ return m_Position;
+}
+//////////////////////////////////////////////////////////
+int32_t CxMemFile::Size()
+{
+ if (m_pBuffer==NULL) return -1;
+ return m_Size;
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::Flush()
+{
+ if (m_pBuffer==NULL) return false;
+ return true;
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::Eof()
+{
+ if (m_pBuffer==NULL) return true;
+ return m_bEOF;
+}
+//////////////////////////////////////////////////////////
+int32_t CxMemFile::Error()
+{
+ if (m_pBuffer==NULL) return -1;
+ return (m_Position > (int32_t)m_Size);
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::PutC(uint8_t c)
+{
+ m_bEOF = false;
+ if (m_pBuffer==NULL) return false;
+
+ if (m_Position >= m_Edge){
+ if (!Alloc(m_Position + 1)){
+ return false;
+ }
+ }
+
+ m_pBuffer[m_Position++] = c;
+
+ if (m_Position > (int32_t)m_Size) m_Size = m_Position;
+
+ return true;
+}
+//////////////////////////////////////////////////////////
+int32_t CxMemFile::GetC()
+{
+ if (m_pBuffer==NULL || m_Position >= (int32_t)m_Size){
+ m_bEOF = true;
+ return EOF;
+ }
+ return *(uint8_t*)((uint8_t*)m_pBuffer + m_Position++);
+}
+//////////////////////////////////////////////////////////
+char * CxMemFile::GetS(char *string, int32_t n)
+{
+ n--;
+ int32_t c,i=0;
+ while (i<n){
+ c = GetC();
+ if (c == EOF) return 0;
+ string[i++] = (char)c;
+ if (c == '\n') break;
+ }
+ string[i] = 0;
+ return string;
+}
+//////////////////////////////////////////////////////////
+int32_t CxMemFile::Scanf(const char *format, void* output)
+{
+ return 0;
+}
+//////////////////////////////////////////////////////////
+bool CxMemFile::Alloc(uint32_t dwNewLen)
+{
+ if (dwNewLen > (uint32_t)m_Edge)
+ {
+ // find new buffer size
+ uint32_t dwNewBufferSize = (uint32_t)(((dwNewLen>>16)+1)<<16);
+
+ // allocate new buffer
+ if (m_pBuffer == NULL) m_pBuffer = (uint8_t*)malloc(dwNewBufferSize);
+ else m_pBuffer = (uint8_t*)realloc(m_pBuffer, dwNewBufferSize);
+ // I own this buffer now (caller knows nothing about it)
+ m_bFreeOnClose = true;
+
+ m_Edge = dwNewBufferSize;
+ }
+ return (m_pBuffer!=0);
+}
+//////////////////////////////////////////////////////////
+void CxMemFile::Free()
+{
+ Close();
+}
+//////////////////////////////////////////////////////////
diff --git a/archive/hge/CxImage/xmemfile.h b/archive/hge/CxImage/xmemfile.h new file mode 100644 index 0000000..e132db3 --- /dev/null +++ b/archive/hge/CxImage/xmemfile.h @@ -0,0 +1,42 @@ +#if !defined(__xmemfile_h)
+#define __xmemfile_h
+
+#include "xfile.h"
+
+//////////////////////////////////////////////////////////
+class DLL_EXP CxMemFile : public CxFile
+{
+public:
+ CxMemFile(uint8_t* pBuffer = NULL, uint32_t size = 0);
+ ~CxMemFile();
+
+ bool Open();
+ uint8_t* GetBuffer(bool bDetachBuffer = true);
+
+ virtual bool Close();
+ virtual size_t Read(void *buffer, size_t size, size_t count);
+ virtual size_t Write(const void *buffer, size_t size, size_t count);
+ virtual bool Seek(int32_t offset, int32_t origin);
+ virtual int32_t Tell();
+ virtual int32_t Size();
+ virtual bool Flush();
+ virtual bool Eof();
+ virtual int32_t Error();
+ virtual bool PutC(uint8_t c);
+ virtual int32_t GetC();
+ virtual char * GetS(char *string, int32_t n);
+ virtual int32_t Scanf(const char *format, void* output);
+
+protected:
+ bool Alloc(uint32_t nBytes);
+ void Free();
+
+ uint8_t* m_pBuffer;
+ uint32_t m_Size;
+ bool m_bFreeOnClose;
+ int32_t m_Position; //current position
+ int32_t m_Edge; //buffer size
+ bool m_bEOF;
+};
+
+#endif
diff --git a/archive/hge/ZLIB/adler32.c b/archive/hge/ZLIB/adler32.c new file mode 100644 index 0000000..65ad6a5 --- /dev/null +++ b/archive/hge/ZLIB/adler32.c @@ -0,0 +1,169 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2007 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/archive/hge/ZLIB/crc32.c b/archive/hge/ZLIB/crc32.c new file mode 100644 index 0000000..91be372 --- /dev/null +++ b/archive/hge/ZLIB/crc32.c @@ -0,0 +1,442 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include <stdio.h> +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include <limits.h> +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/archive/hge/ZLIB/crc32.h b/archive/hge/ZLIB/crc32.h new file mode 100644 index 0000000..8053b61 --- /dev/null +++ b/archive/hge/ZLIB/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/archive/hge/ZLIB/crypt.h b/archive/hge/ZLIB/crypt.h new file mode 100644 index 0000000..c01e587 --- /dev/null +++ b/archive/hge/ZLIB/crypt.h @@ -0,0 +1,136 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +This code is a modified version of crypting code in Infozip distribution + +The encryption/decryption parts of this source code (as opposed to the +non-echoing password parts) were originally written in Europe. The +whole source package can be freely distributed, including from the USA. +(Prior to January 2000, re-export from the US was a violation of US law.) + +This encryption code is a direct transcription of the algorithm from +Roger Schlafly, described by Phil Katz in the file appnote.txt. This +file (appnote.txt) is distributed with the PKZIP program (even in the +version without encryption capabilities). + +If you don't need crypting in your application, just define symbols +NOCRYPT and NOUNCRYPT. + +This code support the "Traditional PKWARE Encryption". + +The new AES encryption added on Zip format by Winzip (see the page +http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong +Encryption is not supported. + */ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long *pkeys, const unsigned long *pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys + 2)) &0xffff) | 2; + return (int)(((temp *(temp ^ 1)) >> 8) &0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long *pkeys, const unsigned long *pcrc_32_tab, int c) +{ + (*(pkeys + 0)) = CRC32((*(pkeys + 0)), c); + (*(pkeys + 1)) += (*(pkeys + 0)) &0xff; + (*(pkeys + 1)) = (*(pkeys + 1)) *134775813L + 1; + { + register int keyshift = (int)((*(pkeys + 1)) >> 24); + (*(pkeys + 2)) = CRC32((*(pkeys + 2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char *passwd, unsigned long *pkeys, const unsigned long *pcrc_32_tab) +{ + *(pkeys + 0) = 305419896L; + *(pkeys + 1) = 591751049L; + *(pkeys + 2) = 878082192L; + while (*passwd != '\0') + { + update_keys(pkeys, pcrc_32_tab, (int) *passwd); + passwd++; + } +} + +//------------------------------------------------------------------------- + +#define zdecode(pkeys,pcrc_32_tab,c) \ +(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ +(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + + #define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ + #ifndef ZCR_SEED2 + #define ZCR_SEED2 3141592654UL /* use PI as default pattern */ + #endif + + static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)const char *passwd; /* password string */ + unsigned char *buf; /* where to write header */ + int bufSize; + unsigned long *pkeys; + const unsigned long *pcrc_32_tab; + unsigned long crcForCrypting; + { + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN - 2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize < RAND_HEAD_LEN) + { + return 0; + } + + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the + * output of rand() to get less predictability, since rand() is + * often poorly implemented. + */ + if (++calls == 1) + { + srand((unsigned)(time(NULL) ^ ZCR_SEED2)); + } + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + c = (rand() >> 7) &0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) &0xff, t); + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) &0xff, t); + return n; + } + +#endif diff --git a/archive/hge/ZLIB/deflate.h b/archive/hge/ZLIB/deflate.h new file mode 100644 index 0000000..cbf0d1e --- /dev/null +++ b/archive/hge/ZLIB/deflate.h @@ -0,0 +1,342 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/archive/hge/ZLIB/inffast.c b/archive/hge/ZLIB/inffast.c new file mode 100644 index 0000000..2f1d60b --- /dev/null +++ b/archive/hge/ZLIB/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/archive/hge/ZLIB/inffast.h b/archive/hge/ZLIB/inffast.h new file mode 100644 index 0000000..e5c1aa4 --- /dev/null +++ b/archive/hge/ZLIB/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/archive/hge/ZLIB/inffixed.h b/archive/hge/ZLIB/inffixed.h new file mode 100644 index 0000000..75ed4b5 --- /dev/null +++ b/archive/hge/ZLIB/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/archive/hge/ZLIB/inflate.c b/archive/hge/ZLIB/inflate.c new file mode 100644 index 0000000..a8431ab --- /dev/null +++ b/archive/hge/ZLIB/inflate.c @@ -0,0 +1,1480 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include <stdio.h> + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/archive/hge/ZLIB/inflate.h b/archive/hge/ZLIB/inflate.h new file mode 100644 index 0000000..95f4986 --- /dev/null +++ b/archive/hge/ZLIB/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/archive/hge/ZLIB/inftrees.c b/archive/hge/ZLIB/inftrees.c new file mode 100644 index 0000000..11e9c52 --- /dev/null +++ b/archive/hge/ZLIB/inftrees.c @@ -0,0 +1,330 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + here.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = here; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/archive/hge/ZLIB/inftrees.h b/archive/hge/ZLIB/inftrees.h new file mode 100644 index 0000000..baa53a0 --- /dev/null +++ b/archive/hge/ZLIB/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/archive/hge/ZLIB/ioapi.c b/archive/hge/ZLIB/ioapi.c new file mode 100644 index 0000000..9ac1985 --- /dev/null +++ b/archive/hge/ZLIB/ioapi.c @@ -0,0 +1,107 @@ +/* ioapi.c -- IO base function header for compress/uncompress .zip +files using zlib + zip or unzip API + +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "zlib.h" +#include "ioapi.h" + + +void *ZCALLBACK fopen_file_func(void *opaque, const char *filename, int mode) +{ + FILE *file = NULL; + + const char *mode_fopen = NULL; + + if ((mode &ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + { + mode_fopen = "rb"; + } + else + { + if (mode &ZLIB_FILEFUNC_MODE_EXISTING) + { + mode_fopen = "r+b"; + } + else + { + if (mode &ZLIB_FILEFUNC_MODE_CREATE) + { + mode_fopen = "wb"; + } + } + } + + if ((filename != NULL) && (mode_fopen != NULL)) + { + file = fopen(filename, mode_fopen); + } + return file; +} + +//------------------------------------------------------------------------- + + +DWORD ZCALLBACK fread_file_func(void *opaque, void *stream, void *buf, DWORD size) +{ + return fread(buf, 1, (size_t)size, (FILE*)stream); +} + +//------------------------------------------------------------------------- + + +DWORD ZCALLBACK fwrite_file_func(void *opaque, void *stream, const void *buf, DWORD size) +{ + return fwrite(buf, 1, (size_t)size, (FILE*)stream); +} + +//------------------------------------------------------------------------- + +long ZCALLBACK ftell_file_func(void *opaque, void *stream) +{ + return ftell((FILE*)stream); +} + +//------------------------------------------------------------------------- + +long ZCALLBACK fseek_file_func(void *opaque, void *stream, DWORD offset, int origin) +{ + fseek((FILE*)stream, offset, origin); + + return 0; +} + +//------------------------------------------------------------------------- + +int ZCALLBACK fclose_file_func(void *opaque, void *stream) +{ + return fclose((FILE*)stream); +} + +//------------------------------------------------------------------------- + +int ZCALLBACK ferror_file_func(void *opaque, void *stream) +{ + return ferror((FILE*)stream); +} + +//------------------------------------------------------------------------- + +void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/archive/hge/ZLIB/ioapi.h b/archive/hge/ZLIB/ioapi.h new file mode 100644 index 0000000..b2ffb14 --- /dev/null +++ b/archive/hge/ZLIB/ioapi.h @@ -0,0 +1,79 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip +files using zlib + zip or unzip API + +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + */ + +#ifndef _ZLIBIOAPI_H + #define _ZLIBIOAPI_H + + + #define ZLIB_FILEFUNC_MODE_READ (1) + #define ZLIB_FILEFUNC_MODE_WRITE (2) + #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + + #define ZLIB_FILEFUNC_MODE_EXISTING (4) + #define ZLIB_FILEFUNC_MODE_CREATE (8) + + // begin ryan. + #ifndef DWORD + #define DWORD uInt + #endif + #ifndef BYTE + #define BYTE Byte + #endif + // end ryan. + + #ifndef ZCALLBACK + + #if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif + #endif + + #ifdef __cplusplus + extern "C" + { + #endif + + typedef void *(ZCALLBACK *open_file_func)(void *opaque, const char *filename, int mode); + typedef DWORD(ZCALLBACK *read_file_func)(void *opaque, void *stream, void *buf, DWORD size); + typedef DWORD(ZCALLBACK *write_file_func)(void *opaque, void *stream, const void *buf, DWORD size); + typedef DWORD(ZCALLBACK *tell_file_func)(void *opaque, void *stream); + typedef DWORD(ZCALLBACK *seek_file_func)(void *opaque, void *stream, DWORD offset, int origin); + typedef int(ZCALLBACK *close_file_func)(void *opaque, void *stream); + typedef int(ZCALLBACK *testerror_file_func)(void *opaque, void *stream); + + typedef struct zlib_filefunc_def_s + { + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + void *opaque; + } zlib_filefunc_def; + + + + void fill_fopen_filefunc OF((zlib_filefunc_def *pzlib_filefunc_def)); + + #define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) + #define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) + #define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) + #define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) + #define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) + #define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + + + #ifdef __cplusplus + } + #endif + +#endif diff --git a/archive/hge/ZLIB/trees.c b/archive/hge/ZLIB/trees.c new file mode 100644 index 0000000..56e9bb1 --- /dev/null +++ b/archive/hge/ZLIB/trees.c @@ -0,0 +1,1244 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include <ctype.h> +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1<<extra_lbits[code]); n++) { + _length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length-1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<<extra_dbits[code]); n++) { + _dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include <stdio.h> +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/archive/hge/ZLIB/trees.h b/archive/hge/ZLIB/trees.h new file mode 100644 index 0000000..d35639d --- /dev/null +++ b/archive/hge/ZLIB/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/archive/hge/ZLIB/uncompr.c b/archive/hge/ZLIB/uncompr.c new file mode 100644 index 0000000..ad98be3 --- /dev/null +++ b/archive/hge/ZLIB/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/archive/hge/ZLIB/unzip.c b/archive/hge/ZLIB/unzip.c new file mode 100644 index 0000000..868f035 --- /dev/null +++ b/archive/hge/ZLIB/unzip.c @@ -0,0 +1,1592 @@ +/* unzip.c -- IO for uncompress .zip files using zlib +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +Read unzip.h for more info + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC + #include <stddef.h> + #include <string.h> + #include <stdlib.h> +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else + #include <errno.h> +#endif + +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO + #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) + #define CASESENSITIVITYDEFAULT_NO + #endif +#endif + + +#ifndef UNZ_BUFSIZE + #define UNZ_BUFSIZE (32768) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP + #define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC + #define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE + #define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ + +typedef struct unz_file_info_internal_s +{ + DWORD offset_curfile; /* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, +when reading and decompress it */ + +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + DWORD pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + DWORD stream_initialised; /* flag set if stream structure is initialised*/ + DWORD offset_local_extrafield; /* offset of the local extra field */ + DWORD size_local_extrafield; /* size of the local extra field */ + DWORD pos_local_extrafield; /* position in the local extra field in read*/ + DWORD crc32; /* crc32 of all data uncompressed */ + DWORD crc32_wait; /* crc32 we must obtain after decompress all */ + DWORD rest_read_compressed; /* number of byte to be decompressed */ + DWORD rest_read_uncompressed; /*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + void *filestream; /* io structore of the zipfile */ + DWORD compression_method; /* compression method (0==store) */ + DWORD byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile + */ +typedef struct +{ + zlib_filefunc_def z_filefunc; + void *filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + DWORD byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + DWORD num_file; /* number of the current file in the zipfile*/ + DWORD pos_in_central_dir; /* pos of the current file in the central dir*/ + DWORD current_file_ok; /* flag about the usability of the current file*/ + DWORD central_pos; /* position of the beginning of the central dir*/ + DWORD size_central_dir; /* size of the central directory */ + DWORD offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s *pfile_in_zip_read; /* structure about the current file if we are decompressing it */ + int encrypted; + + #ifndef NOUNCRYPT + DWORD keys[3]; /* keys defining the pseudo-random sequence */ + const DWORD *pcrc_32_tab; + #endif + +} unz_s; + + +#ifndef NOUNCRYPT + #include "crypt.h" +#endif + +/* =========================================================================== +Read a byte from a gz_stream; update next_in and avail_in. Return EOF +for end of file. +IN assertion: the stream s has been sucessfully opened for reading. + */ + + +static int unzlocal_getByte(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream, int *pi) +{ + BYTE c; + int err = (int)ZREAD(*pzlib_filefunc_def, filestream, &c, 1); + + if (err == 1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def, filestream)) + { + return UNZ_ERRNO; + } + else + { + return UNZ_EOF; + } + } +} + + +/* =========================================================================== +Reads a long in LSB order from the given gz_stream. Sets + */ + +static int unzlocal_getShort(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream, DWORD *pX) +{ + DWORD x; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + + x = (DWORD)i; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + + x += ((DWORD)i) << 8; + + if (err == UNZ_OK) + { + *pX = x; + } + else + { + *pX = 0; + } + + return err; +} + +//------------------------------------------------------------------------- + + +static int unzlocal_getLong(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream, DWORD *pX) +{ + DWORD x; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x = (DWORD)i; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + x += ((DWORD)i) << 8; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + x += ((DWORD)i) << 16; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + x += ((DWORD)i) << 24; + + if (err == UNZ_OK) + { + *pX = x; + } + else + { + *pX = 0; + } + return err; +} + + +//------------------------------------------------------------------------- + + +#ifdef CASESENSITIVITYDEFAULT_NO + #define CASESENSITIVITYDEFAULTVALUE 2 +#else + #define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION + #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* +Compare two filename (fileName1,fileName2). +If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) +If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi +or strcasecmp) +If iCaseSenisivity = 0, case sensitivity is defaut of your operating system +(like 1 on Unix, 2 on Windows) +*/ +/* +extern int ZEXPORT unzStringFileNameCompare(const char *fileName1, const char *fileName2, int iCaseSensitivity) +{ + if (iCaseSensitivity == 0) + { + iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; + } + + if (iCaseSensitivity == 1) + { + return strcmp(fileName1, fileName2); + } + + return stricmp(fileName1, fileName2); +} +*/ +//------------------------------------------------------------------------- + +#ifndef BUFREADCOMMENT + #define BUFREADCOMMENT (0x400) +#endif + +/* +Locate the Central directory of a zipfile (at the end, just before +the global comment) + */ + +static DWORD unzlocal_SearchCentralDir(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream) +{ + BYTE *buf; + DWORD uSizeFile; + DWORD uBackRead; + DWORD uMaxBack = 0xffff; /* maximum size of global comment */ + DWORD uPosFound = 0; + + if (ZSEEK(*pzlib_filefunc_def, filestream, 0, SEEK_END) != 0) + { + return 0; + } + + + uSizeFile = ZTELL(*pzlib_filefunc_def, filestream); + + if (uMaxBack > uSizeFile) + { + uMaxBack = uSizeFile; + } + + buf = (BYTE*)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + { + return 0; + } + + uBackRead = 4; + while (uBackRead < uMaxBack) + { + DWORD uReadSize, uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + { + uBackRead = uMaxBack; + } + else + { + uBackRead += BUFREADCOMMENT; + } + uReadPos = uSizeFile - uBackRead; + + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4): (uSizeFile - uReadPos); + if (ZSEEK(*pzlib_filefunc_def, filestream, uReadPos, SEEK_SET) != 0) + { + break; + } + + if (ZREAD(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + { + break; + } + + for (i = (int)uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) + { + uPosFound = uReadPos + i; + break; + } + + if (uPosFound != 0) + { + break; + } + } + TRYFREE(buf); + return uPosFound; +} + +/* +Open a Zip file. path contain the full pathname (by example, +on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer +"zlib/zlib114.zip". +If the zipfile cannot be opened (file doesn't exist or in not valid), the +return value is NULL. +Else, the return value is a unzFile Handle, usable with other function +of this unzip package. + */ +extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def) +{ + unz_s us; + unz_s *s; + DWORD central_pos, uL; + + DWORD number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + DWORD number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + DWORD number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err = UNZ_OK; + + if (pzlib_filefunc_def == NULL) + { + fill_fopen_filefunc(&us.z_filefunc); + } + else + { + us.z_filefunc = *pzlib_filefunc_def; + } + + us.filestream = (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream == NULL) + { + return NULL; + } + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc, us.filestream); + if (central_pos == 0) + { + err = UNZ_ERRNO; + } + + if (ZSEEK(us.z_filefunc, us.filestream, central_pos, SEEK_SET) != 0) + { + err = UNZ_ERRNO; + } + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if ((number_entry_CD != us.gi.number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) + { + err = UNZ_BADZIPFILE; + } + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if ((central_pos < us.offset_central_dir + us.size_central_dir) && (err == UNZ_OK)) + { + err = UNZ_BADZIPFILE; + } + + if (err != UNZ_OK) + { + ZCLOSE(us.z_filefunc, us.filestream); + return NULL; + } + + us.byte_before_the_zipfile = central_pos - (us.offset_central_dir + us.size_central_dir); + us.central_pos = central_pos; + us.pfile_in_zip_read = NULL; + us.encrypted = 0; + + + s = (unz_s*)ALLOC(sizeof(unz_s)); + *s = us; + unzGoToFirstFile((unzFile)s); + return (unzFile)s; +} + +//------------------------------------------------------------------------- + + +extern unzFile ZEXPORT unzOpen(const char *path) +{ + return unzOpen2(path, NULL); +} + +/* +Close a ZipFile opened with unzipOpen. +If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), +these files MUST be closed with unzipCloseCurrentFile before call unzipClose. +return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzClose(unzFile file) +{ + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + s = (unz_s*)file; + + if (s->pfile_in_zip_read != NULL) + { + unzCloseCurrentFile(file); + } + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* +Write info about the ZipFile in the *pglobal_info structure. +No preparation of the structure is needed +return UNZ_OK if there is no problem. */ +/* +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info) +{ + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + *pglobal_info = s->gi; + return UNZ_OK; +} +*/ + +/* +Translate date/time from Dos format to tm_unz (readable more easilty) + */ + +static void unzlocal_DosDateToTmuDate(DWORD ulDosDate, tm_unz *ptm) +{ + DWORD uDate; + uDate = (DWORD)(ulDosDate >> 16); + ptm->tm_mday = (DWORD)(uDate &0x1f); + ptm->tm_mon = (DWORD)((((uDate) &0x1E0) / 0x20) - 1); + ptm->tm_year = (DWORD)(((uDate &0x0FE00) / 0x0200) + 1980); + + ptm->tm_hour = (DWORD)((ulDosDate &0xF800) / 0x800); + ptm->tm_min = (DWORD)((ulDosDate &0x7E0) / 0x20); + ptm->tm_sec = (DWORD)(2 *(ulDosDate &0x1f)); +} + +/* +Get Info about the current file in the zipfile, with internal only info + */ + +static int unzlocal_GetCurrentFileInfoInternal(unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize) +{ + unz_s *s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err = UNZ_OK; + DWORD uMagic; + long lSeek = 0; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + if (ZSEEK(s->z_filefunc, s->filestream, s->pos_in_central_dir + s->byte_before_the_zipfile, SEEK_SET) != 0) + { + err = UNZ_ERRNO; + } + + /* we check the magic */ + + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if (uMagic != 0x02014b50) + { + err = UNZ_BADZIPFILE; + } + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.flag) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.compression_method) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.crc) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.internal_fa) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.external_fa) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info_internal.offset_curfile) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + lSeek += file_info.size_filename; + + if ((err == UNZ_OK) && (szFileName != NULL)) + { + DWORD uSizeRead; + if (file_info.size_filename < fileNameBufferSize) + { + *(szFileName + file_info.size_filename) = '\0'; + uSizeRead = file_info.size_filename; + } + else + { + uSizeRead = fileNameBufferSize; + } + + if ((file_info.size_filename > 0) && (fileNameBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead) + { + err = UNZ_ERRNO; + } + lSeek -= uSizeRead; + } + + if ((err == UNZ_OK) && (extraField != NULL)) + { + DWORD uSizeRead; + if (file_info.size_file_extra < extraFieldBufferSize) + { + uSizeRead = file_info.size_file_extra; + } + else + { + uSizeRead = extraFieldBufferSize; + } + + if (lSeek != 0) + { + if (ZSEEK(s->z_filefunc, s->filestream, lSeek, SEEK_CUR) == 0) + { + lSeek = 0; + } + else + { + err = UNZ_ERRNO; + } + } + + if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0)) + { + if (ZREAD(s->z_filefunc, s->filestream, extraField, uSizeRead) != uSizeRead) + { + err = UNZ_ERRNO; + } + } + + lSeek += file_info.size_file_extra - uSizeRead; + } + else + { + lSeek += file_info.size_file_extra; + } + + + if ((err == UNZ_OK) && (szComment != NULL)) + { + DWORD uSizeRead; + + if (file_info.size_file_comment < commentBufferSize) + { + *(szComment + file_info.size_file_comment) = '\0'; + uSizeRead = file_info.size_file_comment; + } + else + { + uSizeRead = commentBufferSize; + } + + if (lSeek != 0) + { + if (ZSEEK(s->z_filefunc, s->filestream, lSeek, SEEK_CUR) == 0) + { + lSeek = 0; + } + else + { + err = UNZ_ERRNO; + } + } + + if ((file_info.size_file_comment > 0) && (commentBufferSize > 0)) + { + if (ZREAD(s->z_filefunc, s->filestream, szComment, uSizeRead) != uSizeRead) + { + err = UNZ_ERRNO; + } + } + + lSeek += file_info.size_file_comment - uSizeRead; + } + else + { + lSeek += file_info.size_file_comment; + } + + if ((err == UNZ_OK) && (pfile_info != NULL)) + { + *pfile_info = file_info; + } + + if ((err == UNZ_OK) && (pfile_info_internal != NULL)) + { + *pfile_info_internal = file_info_internal; + } + + return err; +} + + + +/* +Write info about the ZipFile in the *pglobal_info structure. +No preparation of the structure is needed +return UNZ_OK if there is no problem. + */ + +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize); +} + +/* +Set the current file of the zipfile to the first file. +return UNZ_OK if there is no problem + */ + +extern int ZEXPORT unzGoToFirstFile(unzFile file) +{ + int err = UNZ_OK; + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + s->pos_in_central_dir = s->offset_central_dir; + s->num_file = 0; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* +Set the current file of the zipfile to the next file. +return UNZ_OK if there is no problem +return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ + +extern int ZEXPORT unzGoToNextFile(unzFile file) +{ + unz_s *s; + int err; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + if (!s->current_file_ok) + { + return UNZ_END_OF_LIST_OF_FILE; + } + + if (s->gi.number_entry != 0xffff) + { + /* 2^16 files overflow hack */ + if (s->num_file + 1 == s->gi.number_entry) + { + return UNZ_END_OF_LIST_OF_FILE; + } + } + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +extern int ZEXPORT unzGetCurrentFileID(unzFile file, DWORD *file_num, DWORD *pos_in_central_dir) +{ + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + *file_num = s->num_file; + *pos_in_central_dir = s->pos_in_central_dir; + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFileID(unzFile file, DWORD file_num, DWORD pos_in_central_dir) +{ + unz_s *s; + int err; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + s->num_file = file_num; + s->pos_in_central_dir = pos_in_central_dir; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* +Try locate the file szFileName in the zipfile. +For the iCaseSensitivity signification, see unzipStringFileNameCompare + +return value : +UNZ_OK if the file is found. It becomes the current file. +UNZ_END_OF_LIST_OF_FILE if the file is not found + */ + + + +//------------------------------------------------------------------------- + + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// + */ + +/* +Read the local header of the current zipfile +Check the coherency of the local header and info in the end of central +directory about this file +store in *piSizeVar the size of extra info in local header +(filename and size of extra field data) + */ + +static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, DWORD *piSizeVar, DWORD *poffset_local_extrafield, DWORD *psize_local_extrafield) +{ + DWORD uMagic, uData, uFlags; + DWORD size_filename; + DWORD size_extra_field; + int err = UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + + + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if (uMagic != 0x04034b50) + { + err = UNZ_BADZIPFILE; + } + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method)) + { + err = UNZ_BADZIPFILE; + } + + if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // date/time + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // crc + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) && ((uFlags &8) == 0)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // size compr + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) && ((uFlags &8) == 0)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // size uncompr + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) && ((uFlags &8) == 0)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename)) + { + err = UNZ_BADZIPFILE; + } + + *piSizeVar += (DWORD)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (DWORD)size_extra_field; + + *piSizeVar += (DWORD)size_extra_field; + + return err; +} + +/* +Open for reading data the current file in the zipfile. +If there is no error and the file is opened, the return value is UNZ_OK. + */ + +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password) +{ + int err = UNZ_OK; + DWORD iSizeVar; + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + DWORD offset_local_extrafield; // offset of the local extra field + DWORD size_local_extrafield; // size of the local extra field + + #ifndef NOUNCRYPT + char source[12]; + #else + if (password != NULL) + { + return UNZ_PARAMERROR; + } + #endif + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + s = (unz_s*)file; + if (!s->current_file_ok) + { + return UNZ_PARAMERROR; + } + + if (s->pfile_in_zip_read != NULL) + { + unzCloseCurrentFile(file); + } + + if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK) + { + return UNZ_BADZIPFILE; + } + + pfile_in_zip_read_info = (file_in_zip_read_info_s*)ALLOC(sizeof(file_in_zip_read_info_s)); + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->read_buffer = (char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->raw = raw; + + if (pfile_in_zip_read_info->read_buffer == NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised = 0; + + if (method != NULL) + { + *method = (int)s->cur_file_info.compression_method; + } + + if (level != NULL) + { + *level = 6; + switch (s->cur_file_info.flag &0x06) + { + case 6: + *level = 1; + break; + case 4: + *level = 2; + break; + case 2: + *level = 9; + break; + } + } + + if ((s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED)) + { + err = UNZ_BADZIPFILE; + } + + pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; + pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream = s->filestream; + pfile_in_zip_read_info->z_filefunc = s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method == Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (void*)0; + pfile_in_zip_read_info->stream.next_in = (void*)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = inflateInit2(&pfile_in_zip_read_info->stream, - MAX_WBITS); + if (err == Z_OK) + { + pfile_in_zip_read_info->stream_initialised = 1; + } + else + { + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + + pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size; + pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size; + + + pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (DWORD)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + + #ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password, s->keys, s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile, SEEK_SET) != 0) + { + return UNZ_INTERNALERROR; + } + if (ZREAD(s->z_filefunc, s->filestream, source, 12) < 12) + { + return UNZ_INTERNALERROR; + } + + for (i = 0; i < 12; i++) + { + zdecode(s->keys, s->pcrc_32_tab, source[i]); + } + + s->pfile_in_zip_read->pos_in_zipfile += 12; + s->encrypted = 1; + } + #endif + + + return UNZ_OK; +} + +//------------------------------------------------------------------------- + +extern int ZEXPORT unzOpenCurrentFile(unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +//------------------------------------------------------------------------- + +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +//------------------------------------------------------------------------- + +/* +Read bytes from the current file. +buf contain buffer where data must be copied +len the size of buf. + +return the number of byte copied if somes bytes are copied +return 0 if the end of file was reached +return <0 with error code if there is an error +(UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ +extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, DWORD len) +{ + int err = UNZ_OK; + DWORD iRead = 0; + unz_s *s; + + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + { + return UNZ_END_OF_LIST_OF_FILE; + } + + if (len == 0) + { + return 0; + } + + pfile_in_zip_read_info->stream.next_out = (BYTE*)buf; + pfile_in_zip_read_info->stream.avail_out = (DWORD)len; + + if (len > pfile_in_zip_read_info->rest_read_uncompressed) + { + pfile_in_zip_read_info->stream.avail_out = (DWORD)pfile_in_zip_read_info->rest_read_uncompressed; + } + + while (pfile_in_zip_read_info->stream.avail_out > 0) + { + if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed > 0)) + { + DWORD uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressed < uReadThis) + { + uReadThis = (DWORD)pfile_in_zip_read_info->rest_read_compressed; + } + if (uReadThis == 0) + { + return UNZ_EOF; + } + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis) != uReadThis) + { + return UNZ_ERRNO; + } + + #ifndef NOUNCRYPT + if (s->encrypted) + { + DWORD i; + for (i = 0; i < uReadThis; i++) + { + pfile_in_zip_read_info->read_buffer[i] = zdecode(s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]); + } + } + #endif + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed -= uReadThis; + + pfile_in_zip_read_info->stream.next_in = (BYTE*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (DWORD)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) + { + DWORD uDoCopy, i; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) + { + return (iRead == 0) ? UNZ_EOF : iRead; + } + + if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) + { + uDoCopy = pfile_in_zip_read_info->stream.avail_out; + } + else + { + uDoCopy = pfile_in_zip_read_info->stream.avail_in; + } + + for (i = 0; i < uDoCopy; i++) + { + *(pfile_in_zip_read_info->stream.next_out + i) = *(pfile_in_zip_read_info->stream.next_in + i); + } + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + DWORD uTotalOutBefore, uTotalOutAfter; + const BYTE *bufBefore; + DWORD uOutThis; + int flush = Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + err = inflate(&pfile_in_zip_read_info->stream, flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter - uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, bufBefore, (DWORD)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + + iRead += (DWORD)(uTotalOutAfter - uTotalOutBefore); + + if (err == Z_STREAM_END) + { + return (iRead == 0) ? UNZ_EOF : iRead; + } + + if (err != Z_OK) + { + break; + } + } + } + + if (err == Z_OK) + { + return iRead; + } + return err; +} + + +/* +Give the current position in uncompressed data + */ +/* +extern z_off_t ZEXPORT unztell(unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} +*/ + +/* +return 1 if the end of file was reached, 0 elsewhere + */ +/* +extern int ZEXPORT unzeof(unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + return 1; + } + else + { + return 0; + } +} +*/ + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + +if buf==NULL, it return the size of the local extra field that can be read + +if buf!=NULL, len is the size of the buffer, the extra header is copied in +buf. +the return value is the number of bytes copied in buf, or (if <0) +the error code + */ +/* +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, DWORD len) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + DWORD read_now; + DWORD size_to_read; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield); + + if (buf == NULL) + { + return (int)size_to_read; + } + + if (len > size_to_read) + { + read_now = (DWORD)size_to_read; + } + else + { + read_now = (DWORD)len; + } + + if (read_now == 0) + { + return 0; + } + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf, read_now) != read_now) + { + return UNZ_ERRNO; + } + + return (int)read_now; +} +*/ +/* +Close the file in zip opened with unzipOpenCurrentFile +Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ + +extern int ZEXPORT unzCloseCurrentFile(unzFile file) +{ + int err = UNZ_OK; + + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + { + err = UNZ_CRCERROR; + } + } + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + + if (pfile_in_zip_read_info->stream_initialised) + { + inflateEnd(&pfile_in_zip_read_info->stream); + } + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read = NULL; + + return err; +} + + +/* +Get the global comment string of the ZipFile, in the szComment buffer. +uSizeBuf is the size of the szComment buffer. +return the number of byte copied or an error code <0 + */ +/* +extern int ZEXPORT unzGetGlobalComment(unzFile file, char *szComment, DWORD uSizeBuf) +{ + //int err = UNZ_OK; + unz_s *s; + DWORD uReadThis; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + uReadThis = uSizeBuf; + + if (uReadThis > s->gi.size_comment) + { + uReadThis = s->gi.size_comment; + } + + if (ZSEEK(s->z_filefunc, s->filestream, s->central_pos + 22, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + + if (uReadThis > 0) + { + *szComment = '\0'; + + if (ZREAD(s->z_filefunc, s->filestream, szComment, uReadThis) != uReadThis) + { + return UNZ_ERRNO; + } + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + { + *(szComment + s->gi.size_comment) = '\0'; + } + return (int)uReadThis; +} +*/
\ No newline at end of file diff --git a/archive/hge/ZLIB/unzip.h b/archive/hge/ZLIB/unzip.h new file mode 100644 index 0000000..2a9f26f --- /dev/null +++ b/archive/hge/ZLIB/unzip.h @@ -0,0 +1,327 @@ +/* unzip.h -- IO for uncompress .zip files using zlib +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g +WinZip, InfoZip tools and compatible. +Encryption and multi volume ZipFile (span) are not supported. +Old compressions used by old PKZip 1.x are not supported + + +I WAIT FEEDBACK at mail info@winimage.com +Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + +Condition of use and distribution are the same than zlib : + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + + */ + +/* for more info about .ZIP format, see +http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip +http://www.info-zip.org/pub/infozip/doc/ +PkWare has also a specification at : +ftp://ftp.pkware.com/probdesc.zip + */ + +#ifndef _unz_H + #define _unz_H + + #ifdef __cplusplus + extern "C" + { + #endif + + #ifndef _ZLIB_H + #include "zlib.h" + #endif + + #ifndef _ZLIBIOAPI_H + #include "ioapi.h" + #endif + + #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ + typedef struct TagunzFile__ + { + int unused; + } unzFile__; + typedef unzFile__ *unzFile; + #else + typedef void *unzFile; + #endif + + + #define UNZ_OK (0) + #define UNZ_END_OF_LIST_OF_FILE (-100) + #define UNZ_ERRNO (Z_ERRNO) + #define UNZ_EOF (0) + #define UNZ_PARAMERROR (-102) + #define UNZ_BADZIPFILE (-103) + #define UNZ_INTERNALERROR (-104) + #define UNZ_CRCERROR (-105) + + /* tm_unz contain date/time info */ + typedef struct tm_unz_s + { + DWORD tm_sec; /* seconds after the minute - [0,59] */ + DWORD tm_min; /* minutes after the hour - [0,59] */ + DWORD tm_hour; /* hours since midnight - [0,23] */ + DWORD tm_mday; /* day of the month - [1,31] */ + DWORD tm_mon; /* months since January - [0,11] */ + DWORD tm_year; /* years - [1980..2044] */ + } tm_unz; + + /* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ + typedef struct unz_global_info_s + { + DWORD number_entry; /* total number of entries in + the central dir on this disk */ + DWORD size_comment; /* size of the global comment of the zipfile */ + } unz_global_info; + + + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_info_s + { + DWORD version; /* version made by 2 bytes */ + DWORD version_needed; /* version needed to extract 2 bytes */ + DWORD flag; /* general purpose bit flag 2 bytes */ + DWORD compression_method; /* compression method 2 bytes */ + DWORD dosDate; /* last mod file date in Dos fmt 4 bytes */ + DWORD crc; /* crc-32 4 bytes */ + DWORD compressed_size; /* compressed size 4 bytes */ + DWORD uncompressed_size; /* uncompressed size 4 bytes */ + DWORD size_filename; /* filename length 2 bytes */ + DWORD size_file_extra; /* extra field length 2 bytes */ + DWORD size_file_comment; /* file comment length 2 bytes */ + + DWORD disk_num_start; /* disk number start 2 bytes */ + DWORD internal_fa; /* internal file attributes 2 bytes */ + DWORD external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; + } unz_file_info; + + extern int ZEXPORT unzStringFileNameCompare OF((const char *fileName1, const char *fileName2, int iCaseSensitivity)); + /* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + */ + + + extern unzFile ZEXPORT unzOpen(const char *path); + /* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + */ + + extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def); + /* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) + */ + + extern int ZEXPORT unzClose(unzFile file); + /* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + + extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info); + /* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + + extern int ZEXPORT unzGetGlobalComment(unzFile file, char *szComment, DWORD uSizeBuf); + /* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 + */ + + + /***************************************************************************/ + /* Unzip package allow you browse the directory of the zipfile */ + + extern int ZEXPORT unzGoToFirstFile(unzFile file); + /* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem + */ + + extern int ZEXPORT unzGoToNextFile(unzFile file); + /* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ + + extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity); + /* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found + */ + + extern int ZEXPORT unzGetCurrentFileID(unzFile file, DWORD *file_num, DWORD *pos_in_central_dir); + extern int ZEXPORT unzGoToFileID(unzFile file, DWORD file_num, DWORD pos_in_central_dir); + + /* ****************************************** */ + /* Ryan supplied functions */ + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_pos_s + { + DWORD pos_in_zip_directory; /* offset in zip file directory */ + DWORD num_of_file; /* # of file */ + } unz_file_pos; + + extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos); + + extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos); + + /* ****************************************** */ + + extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize); + /* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) + */ + + /***************************************************************************/ + /* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + + extern int ZEXPORT unzOpenCurrentFile(unzFile file); + /* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password); + /* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw); + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password); + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + + extern int ZEXPORT unzCloseCurrentFile(unzFile file); + /* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ + + extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, DWORD len); + /* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ + + extern z_off_t ZEXPORT unztell(unzFile file); + /* + Give the current position in uncompressed data + */ + + extern int ZEXPORT unzeof(unzFile file); + /* + return 1 if the end of file was reached, 0 elsewhere + */ + + extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, DWORD len); + /* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code + */ + + /***************************************************************************/ + + /* Get the current file offset */ + extern DWORD ZEXPORT unzGetOffset(unzFile file); + + /* Set the current file offset */ + extern int ZEXPORT unzSetOffset(unzFile file, DWORD pos); + + + + #ifdef __cplusplus + } + #endif + +#endif /* _unz_H */ diff --git a/archive/hge/ZLIB/zconf.h b/archive/hge/ZLIB/zconf.h new file mode 100644 index 0000000..02ce56c --- /dev/null +++ b/archive/hge/ZLIB/zconf.h @@ -0,0 +1,428 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress +# define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef STDC +# include <sys/types.h> /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include <unistd.h> /* for SEEK_* and off_t */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/archive/hge/ZLIB/zconf.in.h b/archive/hge/ZLIB/zconf.in.h new file mode 100644 index 0000000..91a0f73 --- /dev/null +++ b/archive/hge/ZLIB/zconf.in.h @@ -0,0 +1,323 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.in.h,v 1.1 2005/11/23 14:29:59 stingerx Exp $ */ + +#ifndef ZCONF_H + #define ZCONF_H + + /* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ + #ifdef Z_PREFIX + #define deflateInit_ z_deflateInit_ + #define deflate z_deflate + #define deflateEnd z_deflateEnd + #define inflateInit_ z_inflateInit_ + #define inflate z_inflate + #define inflateEnd z_inflateEnd + #define deflateInit2_ z_deflateInit2_ + #define deflateSetDictionary z_deflateSetDictionary + #define deflateCopy z_deflateCopy + #define deflateReset z_deflateReset + #define deflatePrime z_deflatePrime + #define deflateParams z_deflateParams + #define deflateBound z_deflateBound + #define inflateInit2_ z_inflateInit2_ + #define inflateSetDictionary z_inflateSetDictionary + #define inflateSync z_inflateSync + #define inflateSyncPoint z_inflateSyncPoint + #define inflateCopy z_inflateCopy + #define inflateReset z_inflateReset + #define compress z_compress + #define compress2 z_compress2 + #define compressBound z_compressBound + #define uncompress z_uncompress + #define adler32 z_adler32 + #define crc32 z_crc32 + #define get_crc_table z_get_crc_table + + #define Byte z_Byte + #define uInt z_uInt + #define uLong z_uLong + #define Bytef z_Bytef + #define charf z_charf + #define intf z_intf + #define uIntf z_uIntf + #define uLongf z_uLongf + #define voidpf z_voidpf + #define voidp z_voidp + #endif + + #if defined(__MSDOS__) && !defined(MSDOS) + #define MSDOS + #endif + #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) + #define OS2 + #endif + #if defined(_WINDOWS) && !defined(WINDOWS) + #define WINDOWS + #endif + #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) + #define WIN32 + #endif + #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) + #if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) + #ifndef SYS16BIT + #define SYS16BIT + #endif + #endif + #endif + + /* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ + #ifdef SYS16BIT + #define MAXSEG_64K + #endif + #ifdef MSDOS + #define UNALIGNED_OK + #endif + + #ifdef __STDC_VERSION__ + #ifndef STDC + #define STDC + #endif + #if __STDC_VERSION__ >= 199901L + #ifndef STDC99 + #define STDC99 + #endif + #endif + #endif + #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) + #define STDC + #endif + #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) + #define STDC + #endif + #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) + #define STDC + #endif + #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) + #define STDC + #endif + + #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ + #define STDC + #endif + + #ifndef STDC + #ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ + #define const /* note: need a more gentle solution here */ + #endif + #endif + + /* Some Mac compilers merge all .h files incorrectly: */ + #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) + #define NO_DUMMY_DECL + #endif + + /* Maximum value for memLevel in deflateInit2 */ + #ifndef MAX_MEM_LEVEL + #ifdef MAXSEG_64K + #define MAX_MEM_LEVEL 8 + #else + #define MAX_MEM_LEVEL 9 + #endif + #endif + + /* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ + #ifndef MAX_WBITS + #define MAX_WBITS 15 /* 32K LZ77 window */ + #endif + + /* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. + */ + + /* Type declarations */ + + #ifndef OF /* function prototypes */ + #ifdef STDC + #define OF(args) args + #else + #define OF(args) () + #endif + #endif + + /* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ + #ifdef SYS16BIT + #if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ + #define SMALL_MEDIUM + #ifdef _MSC_VER + #define FAR _far + #else + #define FAR far + #endif + #endif + #if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ + #define SMALL_MEDIUM + #ifdef __BORLANDC__ + #define FAR _far + #else + #define FAR far + #endif + #endif + #endif + + #if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ + #ifdef ZLIB_DLL + #if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) + #ifdef ZLIB_INTERNAL + #define ZEXTERN extern __declspec(dllexport) + #else + #define ZEXTERN extern __declspec(dllimport) + #endif + #endif + #endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ + #ifdef ZLIB_WINAPI + #ifdef FAR + #undef FAR + #endif + #include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ + #define ZEXPORT WINAPI + #ifdef WIN32 + #define ZEXPORTVA WINAPIV + #else + #define ZEXPORTVA FAR CDECL + #endif + #endif + #endif + + #if defined (__BEOS__) + #ifdef ZLIB_DLL + #ifdef ZLIB_INTERNAL + #define ZEXPORT __declspec(dllexport) + #define ZEXPORTVA __declspec(dllexport) + #else + #define ZEXPORT __declspec(dllimport) + #define ZEXPORTVA __declspec(dllimport) + #endif + #endif + #endif + + #ifndef ZEXTERN + #define ZEXTERN extern + #endif + #ifndef ZEXPORT + #define ZEXPORT + #endif + #ifndef ZEXPORTVA + #define ZEXPORTVA + #endif + + #ifndef FAR + #define FAR + #endif + + #if !defined(__MACTYPES__) + typedef unsigned char Byte; /* 8 bits */ + #endif + typedef unsigned int uInt; /* 16 bits or more */ + typedef unsigned long uLong; /* 32 bits or more */ + + #ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ + #define Bytef Byte FAR + #else + typedef Byte FAR Bytef; + #endif + typedef char FAR charf; + typedef int FAR intf; + typedef uInt FAR uIntf; + typedef uLong FAR uLongf; + + #ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; + #else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; + #endif + + #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ + #include <sys/types.h> /* for off_t */ + #include <unistd.h> /* for SEEK_* and off_t */ + #ifdef VMS + #include <unixio.h> /* for off_t */ + #endif + #define z_off_t off_t + #endif + #ifndef SEEK_SET + #define SEEK_SET 0 /* Seek from beginning of file. */ + #define SEEK_CUR 1 /* Seek from current position. */ + #define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ + #endif + #ifndef z_off_t + #define z_off_t long + #endif + + #if defined(__OS400__) + #define NO_vsnprintf + #endif + + #if defined(__MVS__) + #define NO_vsnprintf + #ifdef FAR + #undef FAR + #endif + #endif + + /* MVS linker does not support external names larger than 8 bytes */ + #if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") + #endif + +#endif /* ZCONF_H */ diff --git a/archive/hge/ZLIB/zip.h b/archive/hge/ZLIB/zip.h new file mode 100644 index 0000000..944ed78 --- /dev/null +++ b/archive/hge/ZLIB/zip.h @@ -0,0 +1,196 @@ +/* zip.h -- IO for compress .zip files using zlib +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +This unzip package allow creates .ZIP file, compatible with PKZip 2.04g +WinZip, InfoZip tools and compatible. +Encryption and multi volume ZipFile (span) are not supported. +Old compressions used by old PKZip 1.x are not supported + +For uncompress .zip file, look at unzip.h + + +I WAIT FEEDBACK at mail info@winimage.com +Visit also http://www.winimage.com/zLibDll/unzip.html for evolution + +Condition of use and distribution are the same than zlib : + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + + */ + +/* for more info about .ZIP format, see +http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip +http://www.info-zip.org/pub/infozip/doc/ +PkWare has also a specification at : +ftp://ftp.pkware.com/probdesc.zip + */ + +#ifndef _zip_H + #define _zip_H + + #ifdef __cplusplus + extern "C" + { + #endif + + #ifndef _ZLIB_H + #include "zlib.h" + #endif + + #ifndef _ZLIBIOAPI_H + #include "ioapi.h" + #endif + + #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ + typedef struct TagzipFile__ + { + int unused; + } zipFile__; + typedef zipFile__ *zipFile; + #else + typedef voidp zipFile; + #endif + + #define ZIP_OK (0) + #define ZIP_EOF (0) + #define ZIP_ERRNO (Z_ERRNO) + #define ZIP_PARAMERROR (-102) + #define ZIP_BADZIPFILE (-103) + #define ZIP_INTERNALERROR (-104) + + #ifndef DEF_MEM_LEVEL + #if MAX_MEM_LEVEL >= 8 + #define DEF_MEM_LEVEL 8 + #else + #define DEF_MEM_LEVEL MAX_MEM_LEVEL + #endif + #endif + /* default memLevel */ + + /* tm_zip contain date/time info */ + typedef struct tm_zip_s + { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ + } tm_zip; + + typedef struct + { + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ + /* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + } zip_fileinfo; + + typedef const char *zipcharpc; + + + #define APPEND_STATUS_CREATE (0) + #define APPEND_STATUS_CREATEAFTER (1) + #define APPEND_STATUS_ADDINZIP (2) + + extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); + /* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. + */ + + /* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte + */ + + extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, int append, zipcharpc *globalcomment, zlib_filefunc_def *pzlib_filefunc_def)); + + extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level)); + /* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + */ + + + extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw)); + + /* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + + extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char *password, uLong crcForCtypting)); + + /* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCtypting : crc of file to compress (needed for crypting) + */ + + + extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, const void *buf, unsigned len)); + /* + Write data in the zipfile + */ + + extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); + /* + Close the current file in the zipfile + */ + + extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32)); + /* + Close the current file in the zipfile, for fiel opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size + */ + + extern int ZEXPORT zipClose OF((zipFile file, const char *global_comment)); + /* + Close the zipfile + */ + + #ifdef __cplusplus + } + #endif + +#endif /* _zip_H */ diff --git a/archive/hge/ZLIB/zlib.h b/archive/hge/ZLIB/zlib.h new file mode 100644 index 0000000..bfbba83 --- /dev/null +++ b/archive/hge/ZLIB/zlib.h @@ -0,0 +1,1613 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.5, April 19th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/archive/hge/ZLIB/zutil.c b/archive/hge/ZLIB/zutil.c new file mode 100644 index 0000000..898ed34 --- /dev/null +++ b/archive/hge/ZLIB/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/archive/hge/ZLIB/zutil.h b/archive/hge/ZLIB/zutil.h new file mode 100644 index 0000000..258fa88 --- /dev/null +++ b/archive/hge/ZLIB/zutil.h @@ -0,0 +1,274 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#ifdef STDC +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include <stddef.h> +# endif +# include <string.h> +# include <stdlib.h> +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include <alloc.h> +# endif +# else /* MSC or DJGPP */ +# include <malloc.h> +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 +# include <malloc.h> +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include <unix.h> /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/archive/hge/demo.cpp b/archive/hge/demo.cpp new file mode 100644 index 0000000..a8a2ce3 --- /dev/null +++ b/archive/hge/demo.cpp @@ -0,0 +1,51 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: HGE splash screen +*/ + + +#include "hge_impl.h" +#include "../loading.h" +#include "hgesprite.h" +//#ifdef DEMO +hgeSprite *SprLoad,*SprRot; +HTEXTURE TLoad,TRot; +int px,py; +float dtime,rot; +void DInit() +{ + px=pHGE->System_GetState(HGE_SCREENWIDTH)/2; + py=pHGE->System_GetState(HGE_SCREENHEIGHT)/2; + TLoad=pHGE->Texture_Load((char *)Loading,sizeof(Loading)); + TRot=pHGE->Texture_Load((char *)LoadCircle,sizeof(LoadCircle)); + SprLoad=new hgeSprite(TLoad,0,0,96,32); + SprRot=new hgeSprite(TRot,0,0,48,46); + SprLoad->SetHotSpot(48,16);SprRot->SetHotSpot(24,23); + dtime=0.0f;rot=0.0f; +} +void DDone() +{ + delete SprLoad;delete SprRot; + pHGE->Texture_Free(TLoad);pHGE->Texture_Free(TRot); +} +bool DFrame() +{ + BYTE alpha; + DWORD col=0x00FFFFFF; + dtime+=pHGE->Timer_GetDelta(); + if (dtime<=0.5)alpha=(BYTE)(dtime/0.5f*255.0f);else alpha=255; + if (dtime<=1.5)rot+=((pHGE->Timer_GetDelta())/0.1f)*M_PI*0.3f; + else rot+=((pHGE->Timer_GetDelta())/0.1f)*M_PI*0.3f*((2.0f-dtime)/0.5f); + SprRot->SetColor(SETA(col,alpha)); + if (dtime>=2)return true; + pHGE->Gfx_BeginScene(); + pHGE->Gfx_Clear(0); + SprLoad->Render(px,py); + SprRot->RenderEx(px-75,py,rot); + pHGE->Gfx_EndScene(); + return false; +} +//#endif diff --git a/archive/hge/gl.h b/archive/hge/gl.h new file mode 100644 index 0000000..96fb7d7 --- /dev/null +++ b/archive/hge/gl.h @@ -0,0 +1,2993 @@ +#ifndef __gl_h_ +#define __gl_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: This software was created using the +** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has +** not been independently verified as being compliant with the OpenGL(R) +** version 1.2.1 Specification. +*/ + +// switches to providing function pointers +//#define GL_GLEXT_FUNCTION_POINTERS 1 + +typedef unsigned long GLenum; +typedef unsigned char GLboolean; +typedef unsigned long GLbitfield; +typedef signed char GLbyte; +typedef short GLshort; +typedef long GLint; +typedef long GLsizei; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned long GLuint; +typedef float GLfloat; +typedef float GLclampf; +typedef double GLdouble; +typedef double GLclampd; +typedef void GLvoid; + +typedef long GLintptr; +typedef long GLsizeiptr; + +#ifndef GL_TYPEDEFS_2_0 +#define GL_TYPEDEFS_2_0 + typedef char GLchar; +#endif + +#ifndef GL_GLEXT_LEGACY +#include <OpenGL/glext.h> +#endif + +/* For compatibility with OpenGL v1.0 */ +#define GL_LOGIC_OP GL_INDEX_LOGIC_OP +#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT + +/*************************************************************/ + +/* Version */ +#define GL_VERSION_1_1 1 +#define GL_VERSION_1_2 1 +#define GL_VERSION_1_3 1 +#define GL_VERSION_1_4 1 +#define GL_VERSION_1_5 1 +#define GL_VERSION_2_0 1 + +/* AccumOp */ +#define GL_ACCUM 0x0100 +#define GL_LOAD 0x0101 +#define GL_RETURN 0x0102 +#define GL_MULT 0x0103 +#define GL_ADD 0x0104 + +/* AlphaFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* AttribMask */ +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000fffff + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 + +/* BlendEquationMode */ +/* GL_LOGIC_OP */ +/* GL_FUNC_ADD */ +/* GL_MIN */ +/* GL_MAX */ +/* GL_FUNC_SUBTRACT */ +/* GL_FUNC_REVERSE_SUBTRACT */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +/* GL_CONSTANT_COLOR */ +/* GL_ONE_MINUS_CONSTANT_COLOR */ +/* GL_CONSTANT_ALPHA */ +/* GL_ONE_MINUS_CONSTANT_ALPHA */ + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ +/* GL_CONSTANT_COLOR */ +/* GL_ONE_MINUS_CONSTANT_COLOR */ +/* GL_CONSTANT_ALPHA */ +/* GL_ONE_MINUS_CONSTANT_ALPHA */ + +/* Boolean */ +#define GL_TRUE 1 +#define GL_FALSE 0 + +/* ClearBufferMask */ +/* GL_COLOR_BUFFER_BIT */ +/* GL_ACCUM_BUFFER_BIT */ +/* GL_STENCIL_BUFFER_BIT */ +/* GL_DEPTH_BUFFER_BIT */ + +/* ClientArrayType */ +/* GL_VERTEX_ARRAY */ +/* GL_NORMAL_ARRAY */ +/* GL_COLOR_ARRAY */ +/* GL_INDEX_ARRAY */ +/* GL_TEXTURE_COORD_ARRAY */ +/* GL_EDGE_FLAG_ARRAY */ + +/* ClipPlaneName */ +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 + +/* ColorMaterialFace */ +/* GL_FRONT */ +/* GL_BACK */ +/* GL_FRONT_AND_BACK */ + +/* ColorMaterialParameter */ +/* GL_AMBIENT */ +/* GL_DIFFUSE */ +/* GL_SPECULAR */ +/* GL_EMISSION */ +/* GL_AMBIENT_AND_DIFFUSE */ + +/* ColorPointerType */ +/* GL_BYTE */ +/* GL_UNSIGNED_BYTE */ +/* GL_SHORT */ +/* GL_UNSIGNED_SHORT */ +/* GL_INT */ +/* GL_UNSIGNED_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* ColorTableParameterPName */ +/* GL_COLOR_TABLE_SCALE */ +/* GL_COLOR_TABLE_BIAS */ + +/* ColorTableTarget */ +/* GL_COLOR_TABLE */ +/* GL_POST_CONVOLUTION_COLOR_TABLE */ +/* GL_POST_COLOR_MATRIX_COLOR_TABLE */ +/* GL_PROXY_COLOR_TABLE */ +/* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */ +/* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */ + +/* ConvolutionBorderMode */ +/* GL_REDUCE */ +/* GL_IGNORE_BORDER */ +/* GL_CONSTANT_BORDER */ + +/* ConvolutionParameter */ +/* GL_CONVOLUTION_BORDER_MODE */ +/* GL_CONVOLUTION_FILTER_SCALE */ +/* GL_CONVOLUTION_FILTER_BIAS */ + +/* ConvolutionTarget */ +/* GL_CONVOLUTION_1D */ +/* GL_CONVOLUTION_2D */ + +/* CullFaceMode */ +/* GL_FRONT */ +/* GL_BACK */ +/* GL_FRONT_AND_BACK */ + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* DrawBufferMode */ +#define GL_NONE 0 +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C + +/* Enable */ +/* GL_FOG */ +/* GL_LIGHTING */ +/* GL_TEXTURE_1D */ +/* GL_TEXTURE_2D */ +/* GL_LINE_STIPPLE */ +/* GL_POLYGON_STIPPLE */ +/* GL_CULL_FACE */ +/* GL_ALPHA_TEST */ +/* GL_BLEND */ +/* GL_INDEX_LOGIC_OP */ +/* GL_COLOR_LOGIC_OP */ +/* GL_DITHER */ +/* GL_STENCIL_TEST */ +/* GL_DEPTH_TEST */ +/* GL_CLIP_PLANE0 */ +/* GL_CLIP_PLANE1 */ +/* GL_CLIP_PLANE2 */ +/* GL_CLIP_PLANE3 */ +/* GL_CLIP_PLANE4 */ +/* GL_CLIP_PLANE5 */ +/* GL_LIGHT0 */ +/* GL_LIGHT1 */ +/* GL_LIGHT2 */ +/* GL_LIGHT3 */ +/* GL_LIGHT4 */ +/* GL_LIGHT5 */ +/* GL_LIGHT6 */ +/* GL_LIGHT7 */ +/* GL_TEXTURE_GEN_S */ +/* GL_TEXTURE_GEN_T */ +/* GL_TEXTURE_GEN_R */ +/* GL_TEXTURE_GEN_Q */ +/* GL_MAP1_VERTEX_3 */ +/* GL_MAP1_VERTEX_4 */ +/* GL_MAP1_COLOR_4 */ +/* GL_MAP1_INDEX */ +/* GL_MAP1_NORMAL */ +/* GL_MAP1_TEXTURE_COORD_1 */ +/* GL_MAP1_TEXTURE_COORD_2 */ +/* GL_MAP1_TEXTURE_COORD_3 */ +/* GL_MAP1_TEXTURE_COORD_4 */ +/* GL_MAP2_VERTEX_3 */ +/* GL_MAP2_VERTEX_4 */ +/* GL_MAP2_COLOR_4 */ +/* GL_MAP2_INDEX */ +/* GL_MAP2_NORMAL */ +/* GL_MAP2_TEXTURE_COORD_1 */ +/* GL_MAP2_TEXTURE_COORD_2 */ +/* GL_MAP2_TEXTURE_COORD_3 */ +/* GL_MAP2_TEXTURE_COORD_4 */ +/* GL_POINT_SMOOTH */ +/* GL_LINE_SMOOTH */ +/* GL_POLYGON_SMOOTH */ +/* GL_SCISSOR_TEST */ +/* GL_COLOR_MATERIAL */ +/* GL_NORMALIZE */ +/* GL_AUTO_NORMAL */ +/* GL_VERTEX_ARRAY */ +/* GL_NORMAL_ARRAY */ +/* GL_COLOR_ARRAY */ +/* GL_INDEX_ARRAY */ +/* GL_TEXTURE_COORD_ARRAY */ +/* GL_EDGE_FLAG_ARRAY */ +/* GL_POLYGON_OFFSET_POINT */ +/* GL_POLYGON_OFFSET_LINE */ +/* GL_POLYGON_OFFSET_FILL */ +/* GL_COLOR_TABLE */ +/* GL_POST_CONVOLUTION_COLOR_TABLE */ +/* GL_POST_COLOR_MATRIX_COLOR_TABLE */ +/* GL_CONVOLUTION_1D */ +/* GL_CONVOLUTION_2D */ +/* GL_SEPARABLE_2D */ +/* GL_HISTOGRAM */ +/* GL_MINMAX */ +/* GL_RESCALE_NORMAL */ +/* GL_TEXTURE_3D */ + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 +/* GL_TABLE_TOO_LARGE */ + +/* FeedBackMode */ +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 + +/* FeedBackToken */ +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_LINE_RESET_TOKEN 0x0707 + +/* FogMode */ +/* GL_LINEAR */ +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 + +/* FogParameter */ +/* GL_FOG_COLOR */ +/* GL_FOG_DENSITY */ +/* GL_FOG_END */ +/* GL_FOG_INDEX */ +/* GL_FOG_MODE */ +/* GL_FOG_START */ + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetColorTableParameterPName */ +/* GL_COLOR_TABLE_SCALE */ +/* GL_COLOR_TABLE_BIAS */ +/* GL_COLOR_TABLE_FORMAT */ +/* GL_COLOR_TABLE_WIDTH */ +/* GL_COLOR_TABLE_RED_SIZE */ +/* GL_COLOR_TABLE_GREEN_SIZE */ +/* GL_COLOR_TABLE_BLUE_SIZE */ +/* GL_COLOR_TABLE_ALPHA_SIZE */ +/* GL_COLOR_TABLE_LUMINANCE_SIZE */ +/* GL_COLOR_TABLE_INTENSITY_SIZE */ + +/* GetConvolutionParameterPName */ +/* GL_CONVOLUTION_BORDER_COLOR */ +/* GL_CONVOLUTION_BORDER_MODE */ +/* GL_CONVOLUTION_FILTER_SCALE */ +/* GL_CONVOLUTION_FILTER_BIAS */ +/* GL_CONVOLUTION_FORMAT */ +/* GL_CONVOLUTION_WIDTH */ +/* GL_CONVOLUTION_HEIGHT */ +/* GL_MAX_CONVOLUTION_WIDTH */ +/* GL_MAX_CONVOLUTION_HEIGHT */ + +/* GetHistogramParameterPName */ +/* GL_HISTOGRAM_WIDTH */ +/* GL_HISTOGRAM_FORMAT */ +/* GL_HISTOGRAM_RED_SIZE */ +/* GL_HISTOGRAM_GREEN_SIZE */ +/* GL_HISTOGRAM_BLUE_SIZE */ +/* GL_HISTOGRAM_ALPHA_SIZE */ +/* GL_HISTOGRAM_LUMINANCE_SIZE */ +/* GL_HISTOGRAM_SINK */ + +/* GetMapTarget */ +#define GL_COEFF 0x0A00 +#define GL_ORDER 0x0A01 +#define GL_DOMAIN 0x0A02 + +/* GetMinmaxParameterPName */ +/* GL_MINMAX_FORMAT */ +/* GL_MINMAX_SINK */ + +/* GetPixelMap */ +/* GL_PIXEL_MAP_I_TO_I */ +/* GL_PIXEL_MAP_S_TO_S */ +/* GL_PIXEL_MAP_I_TO_R */ +/* GL_PIXEL_MAP_I_TO_G */ +/* GL_PIXEL_MAP_I_TO_B */ +/* GL_PIXEL_MAP_I_TO_A */ +/* GL_PIXEL_MAP_R_TO_R */ +/* GL_PIXEL_MAP_G_TO_G */ +/* GL_PIXEL_MAP_B_TO_B */ +/* GL_PIXEL_MAP_A_TO_A */ + +/* GetPointerTarget */ +/* GL_VERTEX_ARRAY_POINTER */ +/* GL_NORMAL_ARRAY_POINTER */ +/* GL_COLOR_ARRAY_POINTER */ +/* GL_INDEX_ARRAY_POINTER */ +/* GL_TEXTURE_COORD_ARRAY_POINTER */ +/* GL_EDGE_FLAG_ARRAY_POINTER */ + +/* GetTarget */ +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_RANGE 0x0B12 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_RANGE 0x0B22 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +/* GL_SMOOTH_POINT_SIZE_RANGE */ +/* GL_SMOOTH_POINT_SIZE_GRANULARITY */ +/* GL_SMOOTH_LINE_WIDTH_RANGE */ +/* GL_SMOOTH_LINE_WIDTH_GRANULARITY */ +/* GL_ALIASED_POINT_SIZE_RANGE */ +/* GL_ALIASED_LINE_WIDTH_RANGE */ +#define GL_LIST_MODE 0x0B30 +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_SHADE_MODEL 0x0B54 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_FOG 0x0B60 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_COLOR 0x0B66 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_MATRIX_MODE 0x0BA0 +#define GL_NORMALIZE 0x0BA1 +#define GL_VIEWPORT 0x0BA2 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_FUNC 0x0BC1 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_DITHER 0x0BD0 +#define GL_BLEND_DST 0x0BE0 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_READ_BUFFER 0x0C02 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_INDEX_MODE 0x0C30 +#define GL_RGBA_MODE 0x0C31 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_RENDER_MODE 0x0C40 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_FOG_HINT 0x0C54 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_INDEX_BITS 0x0D51 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 +/* GL_TEXTURE_BINDING_1D */ +/* GL_TEXTURE_BINDING_2D */ +/* GL_TEXTURE_BINDING_3D */ +/* GL_VERTEX_ARRAY */ +/* GL_NORMAL_ARRAY */ +/* GL_COLOR_ARRAY */ +/* GL_INDEX_ARRAY */ +/* GL_TEXTURE_COORD_ARRAY */ +/* GL_EDGE_FLAG_ARRAY */ +/* GL_VERTEX_ARRAY_SIZE */ +/* GL_VERTEX_ARRAY_TYPE */ +/* GL_VERTEX_ARRAY_STRIDE */ +/* GL_NORMAL_ARRAY_TYPE */ +/* GL_NORMAL_ARRAY_STRIDE */ +/* GL_COLOR_ARRAY_SIZE */ +/* GL_COLOR_ARRAY_TYPE */ +/* GL_COLOR_ARRAY_STRIDE */ +/* GL_INDEX_ARRAY_TYPE */ +/* GL_INDEX_ARRAY_STRIDE */ +/* GL_TEXTURE_COORD_ARRAY_SIZE */ +/* GL_TEXTURE_COORD_ARRAY_TYPE */ +/* GL_TEXTURE_COORD_ARRAY_STRIDE */ +/* GL_EDGE_FLAG_ARRAY_STRIDE */ +/* GL_POLYGON_OFFSET_FACTOR */ +/* GL_POLYGON_OFFSET_UNITS */ +/* GL_COLOR_TABLE */ +/* GL_POST_CONVOLUTION_COLOR_TABLE */ +/* GL_POST_COLOR_MATRIX_COLOR_TABLE */ +/* GL_CONVOLUTION_1D */ +/* GL_CONVOLUTION_2D */ +/* GL_SEPARABLE_2D */ +/* GL_POST_CONVOLUTION_RED_SCALE */ +/* GL_POST_CONVOLUTION_GREEN_SCALE */ +/* GL_POST_CONVOLUTION_BLUE_SCALE */ +/* GL_POST_CONVOLUTION_ALPHA_SCALE */ +/* GL_POST_CONVOLUTION_RED_BIAS */ +/* GL_POST_CONVOLUTION_GREEN_BIAS */ +/* GL_POST_CONVOLUTION_BLUE_BIAS */ +/* GL_POST_CONVOLUTION_ALPHA_BIAS */ +/* GL_COLOR_MATRIX */ +/* GL_COLOR_MATRIX_STACK_DEPTH */ +/* GL_MAX_COLOR_MATRIX_STACK_DEPTH */ +/* GL_POST_COLOR_MATRIX_RED_SCALE */ +/* GL_POST_COLOR_MATRIX_GREEN_SCALE */ +/* GL_POST_COLOR_MATRIX_BLUE_SCALE */ +/* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ +/* GL_POST_COLOR_MATRIX_RED_BIAS */ +/* GL_POST_COLOR_MATRIX_GREEN_BIAS */ +/* GL_POST_COLOR_MATRIX_BLUE_BIAS */ +/* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ +/* GL_HISTOGRAM */ +/* GL_MINMAX */ +/* GL_MAX_ELEMENTS_VERTICES */ +/* GL_MAX_ELEMENTS_INDICES */ +/* GL_RESCALE_NORMAL */ +/* GL_LIGHT_MODEL_COLOR_CONTROL */ +/* GL_PACK_SKIP_IMAGES */ +/* GL_PACK_IMAGE_HEIGHT */ +/* GL_UNPACK_SKIP_IMAGES */ +/* GL_UNPACK_IMAGE_HEIGHT */ +/* GL_TEXTURE_3D */ +/* GL_MAX_3D_TEXTURE_SIZE */ +/* GL_BLEND_COLOR */ +/* GL_BLEND_EQUATION */ + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 +/* GL_TEXTURE_RED_SIZE */ +/* GL_TEXTURE_GREEN_SIZE */ +/* GL_TEXTURE_BLUE_SIZE */ +/* GL_TEXTURE_ALPHA_SIZE */ +/* GL_TEXTURE_LUMINANCE_SIZE */ +/* GL_TEXTURE_INTENSITY_SIZE */ +/* GL_TEXTURE_PRIORITY */ +/* GL_TEXTURE_RESIDENT */ +/* GL_TEXTURE_DEPTH */ +/* GL_TEXTURE_WRAP_R */ +/* GL_TEXTURE_MIN_LOD */ +/* GL_TEXTURE_MAX_LOD */ +/* GL_TEXTURE_BASE_LEVEL */ +/* GL_TEXTURE_MAX_LEVEL */ + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +/* GL_PERSPECTIVE_CORRECTION_HINT */ +/* GL_POINT_SMOOTH_HINT */ +/* GL_LINE_SMOOTH_HINT */ +/* GL_POLYGON_SMOOTH_HINT */ +/* GL_FOG_HINT */ + +/* HistogramTarget */ +/* GL_HISTOGRAM */ +/* GL_PROXY_HISTOGRAM */ + +/* IndexPointerType */ +/* GL_SHORT */ +/* GL_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* LightModelColorControl */ +/* GL_SINGLE_COLOR */ +/* GL_SEPARATE_SPECULAR_COLOR */ + +/* LightModelParameter */ +/* GL_LIGHT_MODEL_AMBIENT */ +/* GL_LIGHT_MODEL_LOCAL_VIEWER */ +/* GL_LIGHT_MODEL_TWO_SIDE */ +/* GL_LIGHT_MODEL_COLOR_CONTROL */ + +/* LightName */ +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 + +/* LightParameter */ +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 + +/* InterleavedArrays */ +/* GL_V2F */ +/* GL_V3F */ +/* GL_C4UB_V2F */ +/* GL_C4UB_V3F */ +/* GL_C3F_V3F */ +/* GL_N3F_V3F */ +/* GL_C4F_N3F_V3F */ +/* GL_T2F_V3F */ +/* GL_T4F_V4F */ +/* GL_T2F_C4UB_V3F */ +/* GL_T2F_C3F_V3F */ +/* GL_T2F_N3F_V3F */ +/* GL_T2F_C4F_N3F_V3F */ +/* GL_T4F_C4F_N3F_V4F */ + +/* ListMode */ +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 + +/* ListNameType */ +/* GL_BYTE */ +/* GL_UNSIGNED_BYTE */ +/* GL_SHORT */ +/* GL_UNSIGNED_SHORT */ +/* GL_INT */ +/* GL_UNSIGNED_INT */ +/* GL_FLOAT */ +/* GL_2_BYTES */ +/* GL_3_BYTES */ +/* GL_4_BYTES */ + +/* LogicOp */ +#define GL_CLEAR 0x1500 +#define GL_AND 0x1501 +#define GL_AND_REVERSE 0x1502 +#define GL_COPY 0x1503 +#define GL_AND_INVERTED 0x1504 +#define GL_NOOP 0x1505 +#define GL_XOR 0x1506 +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_EQUIV 0x1509 +#define GL_INVERT 0x150A +#define GL_OR_REVERSE 0x150B +#define GL_COPY_INVERTED 0x150C +#define GL_OR_INVERTED 0x150D +#define GL_NAND 0x150E +#define GL_SET 0x150F + +/* MapTarget */ +/* GL_MAP1_COLOR_4 */ +/* GL_MAP1_INDEX */ +/* GL_MAP1_NORMAL */ +/* GL_MAP1_TEXTURE_COORD_1 */ +/* GL_MAP1_TEXTURE_COORD_2 */ +/* GL_MAP1_TEXTURE_COORD_3 */ +/* GL_MAP1_TEXTURE_COORD_4 */ +/* GL_MAP1_VERTEX_3 */ +/* GL_MAP1_VERTEX_4 */ +/* GL_MAP2_COLOR_4 */ +/* GL_MAP2_INDEX */ +/* GL_MAP2_NORMAL */ +/* GL_MAP2_TEXTURE_COORD_1 */ +/* GL_MAP2_TEXTURE_COORD_2 */ +/* GL_MAP2_TEXTURE_COORD_3 */ +/* GL_MAP2_TEXTURE_COORD_4 */ +/* GL_MAP2_VERTEX_3 */ +/* GL_MAP2_VERTEX_4 */ + +/* MaterialFace */ +/* GL_FRONT */ +/* GL_BACK */ +/* GL_FRONT_AND_BACK */ + +/* MaterialParameter */ +#define GL_EMISSION 0x1600 +#define GL_SHININESS 0x1601 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +/* GL_AMBIENT */ +/* GL_DIFFUSE */ +/* GL_SPECULAR */ + +/* MatrixMode */ +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 + +/* MeshMode1 */ +/* GL_POINT */ +/* GL_LINE */ + +/* MeshMode2 */ +/* GL_POINT */ +/* GL_LINE */ +/* GL_FILL */ + +/* MinmaxTarget */ +/* GL_MINMAX */ + +/* NormalPointerType */ +/* GL_BYTE */ +/* GL_SHORT */ +/* GL_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* PixelCopyType */ +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 + +/* PixelFormat */ +#define GL_COLOR_INDEX 0x1900 +#define GL_STENCIL_INDEX 0x1901 +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +/* GL_ABGR */ + +/* PixelInternalFormat */ +/* GL_ALPHA4 */ +/* GL_ALPHA8 */ +/* GL_ALPHA12 */ +/* GL_ALPHA16 */ +/* GL_LUMINANCE4 */ +/* GL_LUMINANCE8 */ +/* GL_LUMINANCE12 */ +/* GL_LUMINANCE16 */ +/* GL_LUMINANCE4_ALPHA4 */ +/* GL_LUMINANCE6_ALPHA2 */ +/* GL_LUMINANCE8_ALPHA8 */ +/* GL_LUMINANCE12_ALPHA4 */ +/* GL_LUMINANCE12_ALPHA12 */ +/* GL_LUMINANCE16_ALPHA16 */ +/* GL_INTENSITY */ +/* GL_INTENSITY4 */ +/* GL_INTENSITY8 */ +/* GL_INTENSITY12 */ +/* GL_INTENSITY16 */ +/* GL_R3_G3_B2 */ +/* GL_RGB4 */ +/* GL_RGB5 */ +/* GL_RGB8 */ +/* GL_RGB10 */ +/* GL_RGB12 */ +/* GL_RGB16 */ +/* GL_RGBA2 */ +/* GL_RGBA4 */ +/* GL_RGB5_A1 */ +/* GL_RGBA8 */ +/* GL_RGB10_A2 */ +/* GL_RGBA12 */ +/* GL_RGBA16 */ + +/* PixelMap */ +/* GL_PIXEL_MAP_I_TO_I */ +/* GL_PIXEL_MAP_S_TO_S */ +/* GL_PIXEL_MAP_I_TO_R */ +/* GL_PIXEL_MAP_I_TO_G */ +/* GL_PIXEL_MAP_I_TO_B */ +/* GL_PIXEL_MAP_I_TO_A */ +/* GL_PIXEL_MAP_R_TO_R */ +/* GL_PIXEL_MAP_G_TO_G */ +/* GL_PIXEL_MAP_B_TO_B */ +/* GL_PIXEL_MAP_A_TO_A */ + +/* PixelStore */ +/* GL_UNPACK_SWAP_BYTES */ +/* GL_UNPACK_LSB_FIRST */ +/* GL_UNPACK_ROW_LENGTH */ +/* GL_UNPACK_SKIP_ROWS */ +/* GL_UNPACK_SKIP_PIXELS */ +/* GL_UNPACK_ALIGNMENT */ +/* GL_PACK_SWAP_BYTES */ +/* GL_PACK_LSB_FIRST */ +/* GL_PACK_ROW_LENGTH */ +/* GL_PACK_SKIP_ROWS */ +/* GL_PACK_SKIP_PIXELS */ +/* GL_PACK_ALIGNMENT */ +/* GL_PACK_SKIP_IMAGES */ +/* GL_PACK_IMAGE_HEIGHT */ +/* GL_UNPACK_SKIP_IMAGES */ +/* GL_UNPACK_IMAGE_HEIGHT */ + +/* PixelTransfer */ +/* GL_MAP_COLOR */ +/* GL_MAP_STENCIL */ +/* GL_INDEX_SHIFT */ +/* GL_INDEX_OFFSET */ +/* GL_RED_SCALE */ +/* GL_RED_BIAS */ +/* GL_GREEN_SCALE */ +/* GL_GREEN_BIAS */ +/* GL_BLUE_SCALE */ +/* GL_BLUE_BIAS */ +/* GL_ALPHA_SCALE */ +/* GL_ALPHA_BIAS */ +/* GL_DEPTH_SCALE */ +/* GL_DEPTH_BIAS */ +/* GL_POST_CONVOLUTION_RED_SCALE */ +/* GL_POST_CONVOLUTION_GREEN_SCALE */ +/* GL_POST_CONVOLUTION_BLUE_SCALE */ +/* GL_POST_CONVOLUTION_ALPHA_SCALE */ +/* GL_POST_CONVOLUTION_RED_BIAS */ +/* GL_POST_CONVOLUTION_GREEN_BIAS */ +/* GL_POST_CONVOLUTION_BLUE_BIAS */ +/* GL_POST_CONVOLUTION_ALPHA_BIAS */ +/* GL_POST_COLOR_MATRIX_RED_SCALE */ +/* GL_POST_COLOR_MATRIX_GREEN_SCALE */ +/* GL_POST_COLOR_MATRIX_BLUE_SCALE */ +/* GL_POST_COLOR_MATRIX_ALPHA_SCALE */ +/* GL_POST_COLOR_MATRIX_RED_BIAS */ +/* GL_POST_COLOR_MATRIX_GREEN_BIAS */ +/* GL_POST_COLOR_MATRIX_BLUE_BIAS */ +/* GL_POST_COLOR_MATRIX_ALPHA_BIAS */ + +/* PixelType */ +#define GL_BITMAP 0x1A00 +/* GL_BYTE */ +/* GL_UNSIGNED_BYTE */ +/* GL_SHORT */ +/* GL_UNSIGNED_SHORT */ +/* GL_INT */ +/* GL_UNSIGNED_INT */ +/* GL_FLOAT */ +/* GL_BGR */ +/* GL_BGRA */ +/* GL_UNSIGNED_BYTE_3_3_2 */ +/* GL_UNSIGNED_SHORT_4_4_4_4 */ +/* GL_UNSIGNED_SHORT_5_5_5_1 */ +/* GL_UNSIGNED_INT_8_8_8_8 */ +/* GL_UNSIGNED_INT_10_10_10_2 */ +/* GL_UNSIGNED_SHORT_5_6_5 */ +/* GL_UNSIGNED_BYTE_2_3_3_REV */ +/* GL_UNSIGNED_SHORT_5_6_5_REV */ +/* GL_UNSIGNED_SHORT_4_4_4_4_REV */ +/* GL_UNSIGNED_SHORT_1_5_5_5_REV */ +/* GL_UNSIGNED_INT_8_8_8_8_REV */ +/* GL_UNSIGNED_INT_2_10_10_10_REV */ + +/* PolygonMode */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 + +/* ReadBufferMode */ +/* GL_FRONT_LEFT */ +/* GL_FRONT_RIGHT */ +/* GL_BACK_LEFT */ +/* GL_BACK_RIGHT */ +/* GL_FRONT */ +/* GL_BACK */ +/* GL_LEFT */ +/* GL_RIGHT */ +/* GL_AUX0 */ +/* GL_AUX1 */ +/* GL_AUX2 */ +/* GL_AUX3 */ + +/* RenderingMode */ +#define GL_RENDER 0x1C00 +#define GL_FEEDBACK 0x1C01 +#define GL_SELECT 0x1C02 + +/* SeparableTarget */ +/* GL_SEPARABLE_2D */ + +/* ShadingModel */ +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 + +/* StencilFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +/* GL_INVERT */ + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureCoordName */ +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 + +/* TexCoordPointerType */ +/* GL_SHORT */ +/* GL_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* TextureEnvMode */ +#define GL_MODULATE 0x2100 +#define GL_DECAL 0x2101 +/* GL_BLEND */ +/* GL_REPLACE */ + +/* TextureEnvParameter */ +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_ENV_COLOR 0x2201 + +/* TextureEnvTarget */ +#define GL_TEXTURE_ENV 0x2300 + +/* TextureGenMode */ +#define GL_EYE_LINEAR 0x2400 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_SPHERE_MAP 0x2402 + +/* TextureGenParameter */ +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_PLANE 0x2502 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +/* GL_TEXTURE_BORDER_COLOR */ +/* GL_TEXTURE_PRIORITY */ +/* GL_TEXTURE_WRAP_R */ +/* GL_TEXTURE_MIN_LOD */ +/* GL_TEXTURE_MAX_LOD */ +/* GL_TEXTURE_BASE_LEVEL */ +/* GL_TEXTURE_MAX_LEVEL */ + +/* TextureTarget */ +/* GL_TEXTURE_1D */ +/* GL_TEXTURE_2D */ +/* GL_PROXY_TEXTURE_1D */ +/* GL_PROXY_TEXTURE_2D */ +/* GL_TEXTURE_3D */ +/* GL_PROXY_TEXTURE_3D */ + +/* TextureWrapMode */ +#define GL_CLAMP 0x2900 +#define GL_REPEAT 0x2901 +/* GL_CLAMP_TO_EDGE */ + +/* VertexPointerType */ +/* GL_SHORT */ +/* GL_INT */ +/* GL_FLOAT */ +/* GL_DOUBLE */ + +/* ClientAttribMask */ +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff + +/* polygon_offset */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 + +/* texture */ +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 + +/* texture_object */ +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_BINDING_3D 0x806A + +/* vertex_array */ +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +/* bgra */ +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 + +/* blend_color */ +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* blend_minmax */ +#define GL_FUNC_ADD 0x8006 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_BLEND_EQUATION 0x8009 + +/* blend_equation_separate */ +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* blend_subtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* color_matrix */ +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB + +/* color_table */ +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF + +/* convolution */ +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 + +/* draw_range_elements */ +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 + +/* histogram */ +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 + +/* packed_pixels */ +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 + +/* rescale_normal */ +#define GL_RESCALE_NORMAL 0x803A + +/* separate_specular_color */ +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA + +/* texture3D */ +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 + +/* texture_edge_clamp */ +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_CLAMP_TO_BORDER 0x812D + +/* texture_lod */ +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D + +/* GetTarget1_2 */ +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 +#define GL_MAX_TEXTURE_UNITS 0x84E2 + +#define GL_COMBINE 0x8570 +#define GL_COMBINE_RGB 0x8571 +#define GL_COMBINE_ALPHA 0x8572 +#define GL_RGB_SCALE 0x8573 +#define GL_ADD_SIGNED 0x8574 +#define GL_INTERPOLATE 0x8575 +#define GL_CONSTANT 0x8576 +#define GL_PRIMARY_COLOR 0x8577 +#define GL_PREVIOUS 0x8578 +#define GL_SUBTRACT 0x84E7 + +#define GL_SRC0_RGB 0x8580 +#define GL_SRC1_RGB 0x8581 +#define GL_SRC2_RGB 0x8582 +#define GL_SRC3_RGB 0x8583 +#define GL_SRC4_RGB 0x8584 +#define GL_SRC5_RGB 0x8585 +#define GL_SRC6_RGB 0x8586 +#define GL_SRC7_RGB 0x8587 +#define GL_SRC0_ALPHA 0x8588 +#define GL_SRC1_ALPHA 0x8589 +#define GL_SRC2_ALPHA 0x858A +#define GL_SRC3_ALPHA 0x858B +#define GL_SRC4_ALPHA 0x858C +#define GL_SRC5_ALPHA 0x858D +#define GL_SRC6_ALPHA 0x858E +#define GL_SRC7_ALPHA 0x858F + +/* Obsolete */ +#define GL_SOURCE0_RGB 0x8580 +#define GL_SOURCE1_RGB 0x8581 +#define GL_SOURCE2_RGB 0x8582 +#define GL_SOURCE3_RGB 0x8583 +#define GL_SOURCE4_RGB 0x8584 +#define GL_SOURCE5_RGB 0x8585 +#define GL_SOURCE6_RGB 0x8586 +#define GL_SOURCE7_RGB 0x8587 +#define GL_SOURCE0_ALPHA 0x8588 +#define GL_SOURCE1_ALPHA 0x8589 +#define GL_SOURCE2_ALPHA 0x858A +#define GL_SOURCE3_ALPHA 0x858B +#define GL_SOURCE4_ALPHA 0x858C +#define GL_SOURCE5_ALPHA 0x858D +#define GL_SOURCE6_ALPHA 0x858E +#define GL_SOURCE7_ALPHA 0x858F + +#define GL_OPERAND0_RGB 0x8590 +#define GL_OPERAND1_RGB 0x8591 +#define GL_OPERAND2_RGB 0x8592 +#define GL_OPERAND3_RGB 0x8593 +#define GL_OPERAND4_RGB 0x8594 +#define GL_OPERAND5_RGB 0x8595 +#define GL_OPERAND6_RGB 0x8596 +#define GL_OPERAND7_RGB 0x8597 +#define GL_OPERAND0_ALPHA 0x8598 +#define GL_OPERAND1_ALPHA 0x8599 +#define GL_OPERAND2_ALPHA 0x859A +#define GL_OPERAND3_ALPHA 0x859B +#define GL_OPERAND4_ALPHA 0x859C +#define GL_OPERAND5_ALPHA 0x859D +#define GL_OPERAND6_ALPHA 0x859E +#define GL_OPERAND7_ALPHA 0x859F + +#define GL_DOT3_RGB 0x86AE +#define GL_DOT3_RGBA 0x86AF + +#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 + +#define GL_NORMAL_MAP 0x8511 +#define GL_REFLECTION_MAP 0x8512 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +#define GL_COMPRESSED_ALPHA 0x84E9 +#define GL_COMPRESSED_LUMINANCE 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB +#define GL_COMPRESSED_INTENSITY 0x84EC +#define GL_COMPRESSED_RGB 0x84ED +#define GL_COMPRESSED_RGBA 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 +#define GL_TEXTURE_COMPRESSED 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +#define GL_MULTISAMPLE 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE 0x809F +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_MULTISAMPLE_BIT 0x20000000 + +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT24 0x81A6 +#define GL_DEPTH_COMPONENT32 0x81A7 +#define GL_TEXTURE_DEPTH_SIZE 0x884A +#define GL_DEPTH_TEXTURE_MODE 0x884B + +#define GL_TEXTURE_COMPARE_MODE 0x884C +#define GL_TEXTURE_COMPARE_FUNC 0x884D +#define GL_COMPARE_R_TO_TEXTURE 0x884E + +/* occlusion_query */ +#define GL_QUERY_COUNTER_BITS 0x8864 +#define GL_CURRENT_QUERY 0x8865 +#define GL_QUERY_RESULT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE 0x8867 +#define GL_SAMPLES_PASSED 0x8914 + +#define GL_FOG_COORD_SRC 0x8450 +#define GL_FOG_COORD 0x8451 +#define GL_FRAGMENT_DEPTH 0x8452 +#define GL_CURRENT_FOG_COORD 0x8453 +#define GL_FOG_COORD_ARRAY_TYPE 0x8454 +#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORD_ARRAY_POINTER 0x8456 +#define GL_FOG_COORD_ARRAY 0x8457 + +/* Obsolete */ +#define GL_FOG_COORDINATE_SOURCE 0x8450 +#define GL_FOG_COORDINATE 0x8451 +#define GL_CURRENT_FOG_COORDINATE 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 +#define GL_FOG_COORDINATE_ARRAY 0x8457 + +#define GL_COLOR_SUM 0x8458 +#define GL_CURRENT_SECONDARY_COLOR 0x8459 +#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A +#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B +#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C +#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D +#define GL_SECONDARY_COLOR_ARRAY 0x845E + +#define GL_POINT_SIZE_MIN 0x8126 +#define GL_POINT_SIZE_MAX 0x8127 +#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 +#define GL_POINT_DISTANCE_ATTENUATION 0x8129 + +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB + +#define GL_GENERATE_MIPMAP 0x8191 +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +#define GL_MIRRORED_REPEAT 0x8370 + +#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD +#define GL_TEXTURE_FILTER_CONTROL 0x8500 +#define GL_TEXTURE_LOD_BIAS 0x8501 + +/* vertex_buffer_object */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 +#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 +#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 +#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 +#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A +#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B +#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C +#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D +#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_STREAM_DRAW 0x88E0 +#define GL_STREAM_READ 0x88E1 +#define GL_STREAM_COPY 0x88E2 +#define GL_STATIC_DRAW 0x88E4 +#define GL_STATIC_READ 0x88E5 +#define GL_STATIC_COPY 0x88E6 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_DYNAMIC_READ 0x88E9 +#define GL_DYNAMIC_COPY 0x88EA +#define GL_READ_ONLY 0x88B8 +#define GL_WRITE_ONLY 0x88B9 +#define GL_READ_WRITE 0x88BA +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_BUFFER_ACCESS 0x88BB +#define GL_BUFFER_MAPPED 0x88BC +#define GL_BUFFER_MAP_POINTER 0x88BD +/* Obsolete */ +#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D + +/* OpenGL20 */ +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_COMPILE_STATUS 0x8B81 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_1D 0x8B5D +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_3D 0x8B5F +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_SAMPLER_1D_SHADOW 0x8B61 +#define GL_SAMPLER_2D_SHADOW 0x8B62 +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A +#define GL_MAX_VARYING_FLOATS 0x8B4B +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 +#define GL_MAX_TEXTURE_COORDS 0x8871 +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_DRAW_BUFFERS 0x8824 +#define GL_DRAW_BUFFER0 0x8825 +#define GL_DRAW_BUFFER1 0x8826 +#define GL_DRAW_BUFFER2 0x8827 +#define GL_DRAW_BUFFER3 0x8828 +#define GL_DRAW_BUFFER4 0x8829 +#define GL_DRAW_BUFFER5 0x882A +#define GL_DRAW_BUFFER6 0x882B +#define GL_DRAW_BUFFER7 0x882C +#define GL_DRAW_BUFFER8 0x882D +#define GL_DRAW_BUFFER9 0x882E +#define GL_DRAW_BUFFER10 0x882F +#define GL_DRAW_BUFFER11 0x8830 +#define GL_DRAW_BUFFER12 0x8831 +#define GL_DRAW_BUFFER13 0x8832 +#define GL_DRAW_BUFFER14 0x8833 +#define GL_DRAW_BUFFER15 0x8834 +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 +#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 +#define GL_LOWER_LEFT 0x8CA1 +#define GL_UPPER_LEFT 0x8CA2 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + +/*************************************************************/ + +#ifdef GL_GLEXT_FUNCTION_POINTERS +typedef void (* glAccumProcPtr) (GLenum op, GLfloat value); +typedef void (* glAlphaFuncProcPtr) (GLenum func, GLclampf ref); +typedef GLboolean (* glAreTexturesResidentProcPtr) (GLsizei n, const GLuint *textures, GLboolean *residences); +typedef void (* glArrayElementProcPtr) (GLint i); +typedef void (* glBeginProcPtr) (GLenum mode); +typedef void (* glBindTextureProcPtr) (GLenum target, GLuint texture); +typedef void (* glBitmapProcPtr) (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +typedef void (* glBlendColorProcPtr) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (* glBlendEquationProcPtr) (GLenum mode); +typedef void (* glBlendEquationSeparateProcPtr) (GLenum modeRGB, GLenum modeAlpha); +typedef void (* glBlendFuncProcPtr) (GLenum sfactor, GLenum dfactor); +typedef void (* glCallListProcPtr) (GLuint list); +typedef void (* glCallListsProcPtr) (GLsizei n, GLenum type, const GLvoid *lists); +typedef void (* glClearProcPtr) (GLbitfield mask); +typedef void (* glClearAccumProcPtr) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (* glClearColorProcPtr) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +typedef void (* glClearDepthProcPtr) (GLclampd depth); +typedef void (* glClearIndexProcPtr) (GLfloat c); +typedef void (* glClearStencilProcPtr) (GLint s); +typedef void (* glClipPlaneProcPtr) (GLenum plane, const GLdouble *equation); +typedef void (* glColor3bProcPtr) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (* glColor3bvProcPtr) (const GLbyte *v); +typedef void (* glColor3dProcPtr) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (* glColor3dvProcPtr) (const GLdouble *v); +typedef void (* glColor3fProcPtr) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (* glColor3fvProcPtr) (const GLfloat *v); +typedef void (* glColor3iProcPtr) (GLint red, GLint green, GLint blue); +typedef void (* glColor3ivProcPtr) (const GLint *v); +typedef void (* glColor3sProcPtr) (GLshort red, GLshort green, GLshort blue); +typedef void (* glColor3svProcPtr) (const GLshort *v); +typedef void (* glColor3ubProcPtr) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (* glColor3ubvProcPtr) (const GLubyte *v); +typedef void (* glColor3uiProcPtr) (GLuint red, GLuint green, GLuint blue); +typedef void (* glColor3uivProcPtr) (const GLuint *v); +typedef void (* glColor3usProcPtr) (GLushort red, GLushort green, GLushort blue); +typedef void (* glColor3usvProcPtr) (const GLushort *v); +typedef void (* glColor4bProcPtr) (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +typedef void (* glColor4bvProcPtr) (const GLbyte *v); +typedef void (* glColor4dProcPtr) (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +typedef void (* glColor4dvProcPtr) (const GLdouble *v); +typedef void (* glColor4fProcPtr) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (* glColor4fvProcPtr) (const GLfloat *v); +typedef void (* glColor4iProcPtr) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (* glColor4ivProcPtr) (const GLint *v); +typedef void (* glColor4sProcPtr) (GLshort red, GLshort green, GLshort blue, GLshort alpha); +typedef void (* glColor4svProcPtr) (const GLshort *v); +typedef void (* glColor4ubProcPtr) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +typedef void (* glColor4ubvProcPtr) (const GLubyte *v); +typedef void (* glColor4uiProcPtr) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +typedef void (* glColor4uivProcPtr) (const GLuint *v); +typedef void (* glColor4usProcPtr) (GLushort red, GLushort green, GLushort blue, GLushort alpha); +typedef void (* glColor4usvProcPtr) (const GLushort *v); +typedef void (* glColorMaskProcPtr) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (* glColorMaterialProcPtr) (GLenum face, GLenum mode); +typedef void (* glColorPointerProcPtr) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (* glColorSubTableProcPtr) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +typedef void (* glColorTableProcPtr) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +typedef void (* glColorTableParameterfvProcPtr) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (* glColorTableParameterivProcPtr) (GLenum target, GLenum pname, const GLint *params); +typedef void (* glConvolutionFilter1DProcPtr) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +typedef void (* glConvolutionFilter2DProcPtr) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +typedef void (* glConvolutionParameterfProcPtr) (GLenum target, GLenum pname, GLfloat params); +typedef void (* glConvolutionParameterfvProcPtr) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (* glConvolutionParameteriProcPtr) (GLenum target, GLenum pname, GLint params); +typedef void (* glConvolutionParameterivProcPtr) (GLenum target, GLenum pname, const GLint *params); +typedef void (* glCopyColorSubTableProcPtr) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +typedef void (* glCopyColorTableProcPtr) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (* glCopyConvolutionFilter1DProcPtr) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +typedef void (* glCopyConvolutionFilter2DProcPtr) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (* glCopyPixelsProcPtr) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +typedef void (* glCopyTexImage1DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +typedef void (* glCopyTexImage2DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (* glCopyTexSubImage1DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (* glCopyTexSubImage2DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (* glCopyTexSubImage3DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (* glCullFaceProcPtr) (GLenum mode); +typedef void (* glDeleteListsProcPtr) (GLuint list, GLsizei range); +typedef void (* glDeleteTexturesProcPtr) (GLsizei n, const GLuint *textures); +typedef void (* glDepthFuncProcPtr) (GLenum func); +typedef void (* glDepthMaskProcPtr) (GLboolean flag); +typedef void (* glDepthRangeProcPtr) (GLclampd zNear, GLclampd zFar); +typedef void (* glDisableProcPtr) (GLenum cap); +typedef void (* glDisableClientStateProcPtr) (GLenum array); +typedef void (* glDrawArraysProcPtr) (GLenum mode, GLint first, GLsizei count); +typedef void (* glDrawBufferProcPtr) (GLenum mode); +typedef void (* glDrawElementsProcPtr) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (* glDrawPixelsProcPtr) (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glDrawRangeElementsProcPtr) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +typedef void (* glEdgeFlagProcPtr) (GLboolean flag); +typedef void (* glEdgeFlagPointerProcPtr) (GLsizei stride, const GLvoid *pointer); +typedef void (* glEdgeFlagvProcPtr) (const GLboolean *flag); +typedef void (* glEnableProcPtr) (GLenum cap); +typedef void (* glEnableClientStateProcPtr) (GLenum array); +typedef void (* glEndProcPtr) (void); +typedef void (* glEndListProcPtr) (void); +typedef void (* glEvalCoord1dProcPtr) (GLdouble u); +typedef void (* glEvalCoord1dvProcPtr) (const GLdouble *u); +typedef void (* glEvalCoord1fProcPtr) (GLfloat u); +typedef void (* glEvalCoord1fvProcPtr) (const GLfloat *u); +typedef void (* glEvalCoord2dProcPtr) (GLdouble u, GLdouble v); +typedef void (* glEvalCoord2dvProcPtr) (const GLdouble *u); +typedef void (* glEvalCoord2fProcPtr) (GLfloat u, GLfloat v); +typedef void (* glEvalCoord2fvProcPtr) (const GLfloat *u); +typedef void (* glEvalMesh1ProcPtr) (GLenum mode, GLint i1, GLint i2); +typedef void (* glEvalMesh2ProcPtr) (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +typedef void (* glEvalPoint1ProcPtr) (GLint i); +typedef void (* glEvalPoint2ProcPtr) (GLint i, GLint j); +typedef void (* glFeedbackBufferProcPtr) (GLsizei size, GLenum type, GLfloat *buffer); +typedef void (* glFinishProcPtr) (void); +typedef void (* glFlushProcPtr) (void); +typedef void (* glFogfProcPtr) (GLenum pname, GLfloat param); +typedef void (* glFogfvProcPtr) (GLenum pname, const GLfloat *params); +typedef void (* glFogiProcPtr) (GLenum pname, GLint param); +typedef void (* glFogivProcPtr) (GLenum pname, const GLint *params); +typedef void (* glFrontFaceProcPtr) (GLenum mode); +typedef void (* glFrustumProcPtr) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef GLuint (* glGenListsProcPtr) (GLsizei range); +typedef void (* glGenTexturesProcPtr) (GLsizei n, GLuint *textures); +typedef void (* glGetBooleanvProcPtr) (GLenum pname, GLboolean *params); +typedef void (* glGetClipPlaneProcPtr) (GLenum plane, GLdouble *equation); +typedef void (* glGetColorTableProcPtr) (GLenum target, GLenum format, GLenum type, GLvoid *table); +typedef void (* glGetColorTableParameterfvProcPtr) (GLenum target, GLenum pname, GLfloat *params); +typedef void (* glGetColorTableParameterivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetConvolutionFilterProcPtr) (GLenum target, GLenum format, GLenum type, GLvoid *image); +typedef void (* glGetConvolutionParameterfvProcPtr) (GLenum target, GLenum pname, GLfloat *params); +typedef void (* glGetConvolutionParameterivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetDoublevProcPtr) (GLenum pname, GLdouble *params); +typedef GLenum (* glGetErrorProcPtr) (void); +typedef void (* glGetFloatvProcPtr) (GLenum pname, GLfloat *params); +typedef void (* glGetHistogramProcPtr) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (* glGetHistogramParameterfvProcPtr) (GLenum target, GLenum pname, GLfloat *params); +typedef void (* glGetHistogramParameterivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetIntegervProcPtr) (GLenum pname, GLint *params); +typedef void (* glGetLightfvProcPtr) (GLenum light, GLenum pname, GLfloat *params); +typedef void (* glGetLightivProcPtr) (GLenum light, GLenum pname, GLint *params); +typedef void (* glGetMapdvProcPtr) (GLenum target, GLenum query, GLdouble *v); +typedef void (* glGetMapfvProcPtr) (GLenum target, GLenum query, GLfloat *v); +typedef void (* glGetMapivProcPtr) (GLenum target, GLenum query, GLint *v); +typedef void (* glGetMaterialfvProcPtr) (GLenum face, GLenum pname, GLfloat *params); +typedef void (* glGetMaterialivProcPtr) (GLenum face, GLenum pname, GLint *params); +typedef void (* glGetMinmaxProcPtr) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +typedef void (* glGetMinmaxParameterfvProcPtr) (GLenum target, GLenum pname, GLfloat *params); +typedef void (* glGetMinmaxParameterivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetPixelMapfvProcPtr) (GLenum map, GLfloat *values); +typedef void (* glGetPixelMapuivProcPtr) (GLenum map, GLuint *values); +typedef void (* glGetPixelMapusvProcPtr) (GLenum map, GLushort *values); +typedef void (* glGetPointervProcPtr) (GLenum pname, GLvoid* *params); +typedef void (* glGetPolygonStippleProcPtr) (GLubyte *mask); +typedef void (* glGetSeparableFilterProcPtr) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +typedef const GLubyte * (* glGetStringProcPtr) (GLenum name); +typedef void (* glGetTexEnvfvProcPtr) (GLenum target, GLenum pname, GLfloat *params); +typedef void (* glGetTexEnvivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetTexGendvProcPtr) (GLenum coord, GLenum pname, GLdouble *params); +typedef void (* glGetTexGenfvProcPtr) (GLenum coord, GLenum pname, GLfloat *params); +typedef void (* glGetTexGenivProcPtr) (GLenum coord, GLenum pname, GLint *params); +typedef void (* glGetTexImageProcPtr) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +typedef void (* glGetTexLevelParameterfvProcPtr) (GLenum target, GLint level, GLenum pname, GLfloat *params); +typedef void (* glGetTexLevelParameterivProcPtr) (GLenum target, GLint level, GLenum pname, GLint *params); +typedef void (* glGetTexParameterfvProcPtr) (GLenum target, GLenum pname, GLfloat *params); +typedef void (* glGetTexParameterivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glHintProcPtr) (GLenum target, GLenum mode); +typedef void (* glHistogramProcPtr) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +typedef void (* glIndexMaskProcPtr) (GLuint mask); +typedef void (* glIndexPointerProcPtr) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (* glIndexdProcPtr) (GLdouble c); +typedef void (* glIndexdvProcPtr) (const GLdouble *c); +typedef void (* glIndexfProcPtr) (GLfloat c); +typedef void (* glIndexfvProcPtr) (const GLfloat *c); +typedef void (* glIndexiProcPtr) (GLint c); +typedef void (* glIndexivProcPtr) (const GLint *c); +typedef void (* glIndexsProcPtr) (GLshort c); +typedef void (* glIndexsvProcPtr) (const GLshort *c); +typedef void (* glIndexubProcPtr) (GLubyte c); +typedef void (* glIndexubvProcPtr) (const GLubyte *c); +typedef void (* glInitNamesProcPtr) (void); +typedef void (* glInterleavedArraysProcPtr) (GLenum format, GLsizei stride, const GLvoid *pointer); +typedef GLboolean (* glIsEnabledProcPtr) (GLenum cap); +typedef GLboolean (* glIsListProcPtr) (GLuint list); +typedef GLboolean (* glIsTextureProcPtr) (GLuint texture); +typedef void (* glLightModelfProcPtr) (GLenum pname, GLfloat param); +typedef void (* glLightModelfvProcPtr) (GLenum pname, const GLfloat *params); +typedef void (* glLightModeliProcPtr) (GLenum pname, GLint param); +typedef void (* glLightModelivProcPtr) (GLenum pname, const GLint *params); +typedef void (* glLightfProcPtr) (GLenum light, GLenum pname, GLfloat param); +typedef void (* glLightfvProcPtr) (GLenum light, GLenum pname, const GLfloat *params); +typedef void (* glLightiProcPtr) (GLenum light, GLenum pname, GLint param); +typedef void (* glLightivProcPtr) (GLenum light, GLenum pname, const GLint *params); +typedef void (* glLineStippleProcPtr) (GLint factor, GLushort pattern); +typedef void (* glLineWidthProcPtr) (GLfloat width); +typedef void (* glListBaseProcPtr) (GLuint base); +typedef void (* glLoadIdentityProcPtr) (void); +typedef void (* glLoadMatrixdProcPtr) (const GLdouble *m); +typedef void (* glLoadMatrixfProcPtr) (const GLfloat *m); +typedef void (* glLoadNameProcPtr) (GLuint name); +typedef void (* glLogicOpProcPtr) (GLenum opcode); +typedef void (* glMap1dProcPtr) (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +typedef void (* glMap1fProcPtr) (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +typedef void (* glMap2dProcPtr) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +typedef void (* glMap2fProcPtr) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +typedef void (* glMapGrid1dProcPtr) (GLint un, GLdouble u1, GLdouble u2); +typedef void (* glMapGrid1fProcPtr) (GLint un, GLfloat u1, GLfloat u2); +typedef void (* glMapGrid2dProcPtr) (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +typedef void (* glMapGrid2fProcPtr) (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +typedef void (* glMaterialfProcPtr) (GLenum face, GLenum pname, GLfloat param); +typedef void (* glMaterialfvProcPtr) (GLenum face, GLenum pname, const GLfloat *params); +typedef void (* glMaterialiProcPtr) (GLenum face, GLenum pname, GLint param); +typedef void (* glMaterialivProcPtr) (GLenum face, GLenum pname, const GLint *params); +typedef void (* glMatrixModeProcPtr) (GLenum mode); +typedef void (* glMinmaxProcPtr) (GLenum target, GLenum internalformat, GLboolean sink); +typedef void (* glMultMatrixdProcPtr) (const GLdouble *m); +typedef void (* glMultMatrixfProcPtr) (const GLfloat *m); +typedef void (* glNewListProcPtr) (GLuint list, GLenum mode); +typedef void (* glNormal3bProcPtr) (GLbyte nx, GLbyte ny, GLbyte nz); +typedef void (* glNormal3bvProcPtr) (const GLbyte *v); +typedef void (* glNormal3dProcPtr) (GLdouble nx, GLdouble ny, GLdouble nz); +typedef void (* glNormal3dvProcPtr) (const GLdouble *v); +typedef void (* glNormal3fProcPtr) (GLfloat nx, GLfloat ny, GLfloat nz); +typedef void (* glNormal3fvProcPtr) (const GLfloat *v); +typedef void (* glNormal3iProcPtr) (GLint nx, GLint ny, GLint nz); +typedef void (* glNormal3ivProcPtr) (const GLint *v); +typedef void (* glNormal3sProcPtr) (GLshort nx, GLshort ny, GLshort nz); +typedef void (* glNormal3svProcPtr) (const GLshort *v); +typedef void (* glNormalPointerProcPtr) (GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (* glOrthoProcPtr) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (* glPassThroughProcPtr) (GLfloat token); +typedef void (* glPixelMapfvProcPtr) (GLenum map, GLint mapsize, const GLfloat *values); +typedef void (* glPixelMapuivProcPtr) (GLenum map, GLint mapsize, const GLuint *values); +typedef void (* glPixelMapusvProcPtr) (GLenum map, GLint mapsize, const GLushort *values); +typedef void (* glPixelStorefProcPtr) (GLenum pname, GLfloat param); +typedef void (* glPixelStoreiProcPtr) (GLenum pname, GLint param); +typedef void (* glPixelTransferfProcPtr) (GLenum pname, GLfloat param); +typedef void (* glPixelTransferiProcPtr) (GLenum pname, GLint param); +typedef void (* glPixelZoomProcPtr) (GLfloat xfactor, GLfloat yfactor); +typedef void (* glPointSizeProcPtr) (GLfloat size); +typedef void (* glPolygonModeProcPtr) (GLenum face, GLenum mode); +typedef void (* glPolygonOffsetProcPtr) (GLfloat factor, GLfloat units); +typedef void (* glPolygonStippleProcPtr) (const GLubyte *mask); +typedef void (* glPopAttribProcPtr) (void); +typedef void (* glPopClientAttribProcPtr) (void); +typedef void (* glPopMatrixProcPtr) (void); +typedef void (* glPopNameProcPtr) (void); +typedef void (* glPrioritizeTexturesProcPtr) (GLsizei n, const GLuint *textures, const GLclampf *priorities); +typedef void (* glPushAttribProcPtr) (GLbitfield mask); +typedef void (* glPushClientAttribProcPtr) (GLbitfield mask); +typedef void (* glPushMatrixProcPtr) (void); +typedef void (* glPushNameProcPtr) (GLuint name); +typedef void (* glRasterPos2dProcPtr) (GLdouble x, GLdouble y); +typedef void (* glRasterPos2dvProcPtr) (const GLdouble *v); +typedef void (* glRasterPos2fProcPtr) (GLfloat x, GLfloat y); +typedef void (* glRasterPos2fvProcPtr) (const GLfloat *v); +typedef void (* glRasterPos2iProcPtr) (GLint x, GLint y); +typedef void (* glRasterPos2ivProcPtr) (const GLint *v); +typedef void (* glRasterPos2sProcPtr) (GLshort x, GLshort y); +typedef void (* glRasterPos2svProcPtr) (const GLshort *v); +typedef void (* glRasterPos3dProcPtr) (GLdouble x, GLdouble y, GLdouble z); +typedef void (* glRasterPos3dvProcPtr) (const GLdouble *v); +typedef void (* glRasterPos3fProcPtr) (GLfloat x, GLfloat y, GLfloat z); +typedef void (* glRasterPos3fvProcPtr) (const GLfloat *v); +typedef void (* glRasterPos3iProcPtr) (GLint x, GLint y, GLint z); +typedef void (* glRasterPos3ivProcPtr) (const GLint *v); +typedef void (* glRasterPos3sProcPtr) (GLshort x, GLshort y, GLshort z); +typedef void (* glRasterPos3svProcPtr) (const GLshort *v); +typedef void (* glRasterPos4dProcPtr) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (* glRasterPos4dvProcPtr) (const GLdouble *v); +typedef void (* glRasterPos4fProcPtr) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (* glRasterPos4fvProcPtr) (const GLfloat *v); +typedef void (* glRasterPos4iProcPtr) (GLint x, GLint y, GLint z, GLint w); +typedef void (* glRasterPos4ivProcPtr) (const GLint *v); +typedef void (* glRasterPos4sProcPtr) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (* glRasterPos4svProcPtr) (const GLshort *v); +typedef void (* glReadBufferProcPtr) (GLenum mode); +typedef void (* glReadPixelsProcPtr) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +typedef void (* glRectdProcPtr) (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +typedef void (* glRectdvProcPtr) (const GLdouble *v1, const GLdouble *v2); +typedef void (* glRectfProcPtr) (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +typedef void (* glRectfvProcPtr) (const GLfloat *v1, const GLfloat *v2); +typedef void (* glRectiProcPtr) (GLint x1, GLint y1, GLint x2, GLint y2); +typedef void (* glRectivProcPtr) (const GLint *v1, const GLint *v2); +typedef void (* glRectsProcPtr) (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +typedef void (* glRectsvProcPtr) (const GLshort *v1, const GLshort *v2); +typedef GLint (* glRenderModeProcPtr) (GLenum mode); +typedef void (* glResetHistogramProcPtr) (GLenum target); +typedef void (* glResetMinmaxProcPtr) (GLenum target); +typedef void (* glRotatedProcPtr) (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (* glRotatefProcPtr) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (* glScaledProcPtr) (GLdouble x, GLdouble y, GLdouble z); +typedef void (* glScalefProcPtr) (GLfloat x, GLfloat y, GLfloat z); +typedef void (* glScissorProcPtr) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (* glSelectBufferProcPtr) (GLsizei size, GLuint *buffer); +typedef void (* glSeparableFilter2DProcPtr) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +typedef void (* glShadeModelProcPtr) (GLenum mode); +typedef void (* glStencilFuncProcPtr) (GLenum func, GLint ref, GLuint mask); +typedef void (* glStencilMaskProcPtr) (GLuint mask); +typedef void (* glStencilOpProcPtr) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (* glTexCoord1dProcPtr) (GLdouble s); +typedef void (* glTexCoord1dvProcPtr) (const GLdouble *v); +typedef void (* glTexCoord1fProcPtr) (GLfloat s); +typedef void (* glTexCoord1fvProcPtr) (const GLfloat *v); +typedef void (* glTexCoord1iProcPtr) (GLint s); +typedef void (* glTexCoord1ivProcPtr) (const GLint *v); +typedef void (* glTexCoord1sProcPtr) (GLshort s); +typedef void (* glTexCoord1svProcPtr) (const GLshort *v); +typedef void (* glTexCoord2dProcPtr) (GLdouble s, GLdouble t); +typedef void (* glTexCoord2dvProcPtr) (const GLdouble *v); +typedef void (* glTexCoord2fProcPtr) (GLfloat s, GLfloat t); +typedef void (* glTexCoord2fvProcPtr) (const GLfloat *v); +typedef void (* glTexCoord2iProcPtr) (GLint s, GLint t); +typedef void (* glTexCoord2ivProcPtr) (const GLint *v); +typedef void (* glTexCoord2sProcPtr) (GLshort s, GLshort t); +typedef void (* glTexCoord2svProcPtr) (const GLshort *v); +typedef void (* glTexCoord3dProcPtr) (GLdouble s, GLdouble t, GLdouble r); +typedef void (* glTexCoord3dvProcPtr) (const GLdouble *v); +typedef void (* glTexCoord3fProcPtr) (GLfloat s, GLfloat t, GLfloat r); +typedef void (* glTexCoord3fvProcPtr) (const GLfloat *v); +typedef void (* glTexCoord3iProcPtr) (GLint s, GLint t, GLint r); +typedef void (* glTexCoord3ivProcPtr) (const GLint *v); +typedef void (* glTexCoord3sProcPtr) (GLshort s, GLshort t, GLshort r); +typedef void (* glTexCoord3svProcPtr) (const GLshort *v); +typedef void (* glTexCoord4dProcPtr) (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (* glTexCoord4dvProcPtr) (const GLdouble *v); +typedef void (* glTexCoord4fProcPtr) (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (* glTexCoord4fvProcPtr) (const GLfloat *v); +typedef void (* glTexCoord4iProcPtr) (GLint s, GLint t, GLint r, GLint q); +typedef void (* glTexCoord4ivProcPtr) (const GLint *v); +typedef void (* glTexCoord4sProcPtr) (GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (* glTexCoord4svProcPtr) (const GLshort *v); +typedef void (* glTexCoordPointerProcPtr) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (* glTexEnvfProcPtr) (GLenum target, GLenum pname, GLfloat param); +typedef void (* glTexEnvfvProcPtr) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (* glTexEnviProcPtr) (GLenum target, GLenum pname, GLint param); +typedef void (* glTexEnvivProcPtr) (GLenum target, GLenum pname, const GLint *params); +typedef void (* glTexGendProcPtr) (GLenum coord, GLenum pname, GLdouble param); +typedef void (* glTexGendvProcPtr) (GLenum coord, GLenum pname, const GLdouble *params); +typedef void (* glTexGenfProcPtr) (GLenum coord, GLenum pname, GLfloat param); +typedef void (* glTexGenfvProcPtr) (GLenum coord, GLenum pname, const GLfloat *params); +typedef void (* glTexGeniProcPtr) (GLenum coord, GLenum pname, GLint param); +typedef void (* glTexGenivProcPtr) (GLenum coord, GLenum pname, const GLint *params); +typedef void (* glTexImage1DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glTexImage2DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glTexImage3DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glTexParameterfProcPtr) (GLenum target, GLenum pname, GLfloat param); +typedef void (* glTexParameterfvProcPtr) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (* glTexParameteriProcPtr) (GLenum target, GLenum pname, GLint param); +typedef void (* glTexParameterivProcPtr) (GLenum target, GLenum pname, const GLint *params); +typedef void (* glTexSubImage1DProcPtr) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glTexSubImage2DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glTexSubImage3DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +typedef void (* glTranslatedProcPtr) (GLdouble x, GLdouble y, GLdouble z); +typedef void (* glTranslatefProcPtr) (GLfloat x, GLfloat y, GLfloat z); +typedef void (* glVertex2dProcPtr) (GLdouble x, GLdouble y); +typedef void (* glVertex2dvProcPtr) (const GLdouble *v); +typedef void (* glVertex2fProcPtr) (GLfloat x, GLfloat y); +typedef void (* glVertex2fvProcPtr) (const GLfloat *v); +typedef void (* glVertex2iProcPtr) (GLint x, GLint y); +typedef void (* glVertex2ivProcPtr) (const GLint *v); +typedef void (* glVertex2sProcPtr) (GLshort x, GLshort y); +typedef void (* glVertex2svProcPtr) (const GLshort *v); +typedef void (* glVertex3dProcPtr) (GLdouble x, GLdouble y, GLdouble z); +typedef void (* glVertex3dvProcPtr) (const GLdouble *v); +typedef void (* glVertex3fProcPtr) (GLfloat x, GLfloat y, GLfloat z); +typedef void (* glVertex3fvProcPtr) (const GLfloat *v); +typedef void (* glVertex3iProcPtr) (GLint x, GLint y, GLint z); +typedef void (* glVertex3ivProcPtr) (const GLint *v); +typedef void (* glVertex3sProcPtr) (GLshort x, GLshort y, GLshort z); +typedef void (* glVertex3svProcPtr) (const GLshort *v); +typedef void (* glVertex4dProcPtr) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (* glVertex4dvProcPtr) (const GLdouble *v); +typedef void (* glVertex4fProcPtr) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (* glVertex4fvProcPtr) (const GLfloat *v); +typedef void (* glVertex4iProcPtr) (GLint x, GLint y, GLint z, GLint w); +typedef void (* glVertex4ivProcPtr) (const GLint *v); +typedef void (* glVertex4sProcPtr) (GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (* glVertex4svProcPtr) (const GLshort *v); +typedef void (* glVertexPointerProcPtr) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (* glViewportProcPtr) (GLint x, GLint y, GLsizei width, GLsizei height); + +typedef void (* glSampleCoverageProcPtr) (GLclampf value, GLboolean invert); +typedef void (* glSamplePassProcPtr) (GLenum pass); + +typedef void (* glLoadTransposeMatrixfProcPtr) (const GLfloat *m); +typedef void (* glLoadTransposeMatrixdProcPtr) (const GLdouble *m); +typedef void (* glMultTransposeMatrixfProcPtr) (const GLfloat *m); +typedef void (* glMultTransposeMatrixdProcPtr) (const GLdouble *m); + +typedef void (* glCompressedTexImage3DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (* glCompressedTexImage2DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (* glCompressedTexImage1DProcPtr) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +typedef void (* glCompressedTexSubImage3DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (* glCompressedTexSubImage2DProcPtr) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (* glCompressedTexSubImage1DProcPtr) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +typedef void (* glGetCompressedTexImageProcPtr) (GLenum target, GLint lod, GLvoid *img); + +typedef void (* glActiveTextureProcPtr) (GLenum texture); +typedef void (* glClientActiveTextureProcPtr) (GLenum texture); +typedef void (* glMultiTexCoord1dProcPtr) (GLenum target, GLdouble s); +typedef void (* glMultiTexCoord1dvProcPtr) (GLenum target, const GLdouble *v); +typedef void (* glMultiTexCoord1fProcPtr) (GLenum target, GLfloat s); +typedef void (* glMultiTexCoord1fvProcPtr) (GLenum target, const GLfloat *v); +typedef void (* glMultiTexCoord1iProcPtr) (GLenum target, GLint s); +typedef void (* glMultiTexCoord1ivProcPtr) (GLenum target, const GLint *v); +typedef void (* glMultiTexCoord1sProcPtr) (GLenum target, GLshort s); +typedef void (* glMultiTexCoord1svProcPtr) (GLenum target, const GLshort *v); +typedef void (* glMultiTexCoord2dProcPtr) (GLenum target, GLdouble s, GLdouble t); +typedef void (* glMultiTexCoord2dvProcPtr) (GLenum target, const GLdouble *v); +typedef void (* glMultiTexCoord2fProcPtr) (GLenum target, GLfloat s, GLfloat t); +typedef void (* glMultiTexCoord2fvProcPtr) (GLenum target, const GLfloat *v); +typedef void (* glMultiTexCoord2iProcPtr) (GLenum target, GLint s, GLint t); +typedef void (* glMultiTexCoord2ivProcPtr) (GLenum target, const GLint *v); +typedef void (* glMultiTexCoord2sProcPtr) (GLenum target, GLshort s, GLshort t); +typedef void (* glMultiTexCoord2svProcPtr) (GLenum target, const GLshort *v); +typedef void (* glMultiTexCoord3dProcPtr) (GLenum target, GLdouble s, GLdouble t, GLdouble r); +typedef void (* glMultiTexCoord3dvProcPtr) (GLenum target, const GLdouble *v); +typedef void (* glMultiTexCoord3fProcPtr) (GLenum target, GLfloat s, GLfloat t, GLfloat r); +typedef void (* glMultiTexCoord3fvProcPtr) (GLenum target, const GLfloat *v); +typedef void (* glMultiTexCoord3iProcPtr) (GLenum target, GLint s, GLint t, GLint r); +typedef void (* glMultiTexCoord3ivProcPtr) (GLenum target, const GLint *v); +typedef void (* glMultiTexCoord3sProcPtr) (GLenum target, GLshort s, GLshort t, GLshort r); +typedef void (* glMultiTexCoord3svProcPtr) (GLenum target, const GLshort *v); +typedef void (* glMultiTexCoord4dProcPtr) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +typedef void (* glMultiTexCoord4dvProcPtr) (GLenum target, const GLdouble *v); +typedef void (* glMultiTexCoord4fProcPtr) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +typedef void (* glMultiTexCoord4fvProcPtr) (GLenum target, const GLfloat *v); +typedef void (* glMultiTexCoord4iProcPtr) (GLenum target, GLint, GLint s, GLint t, GLint r); +typedef void (* glMultiTexCoord4ivProcPtr) (GLenum target, const GLint *v); +typedef void (* glMultiTexCoord4sProcPtr) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +typedef void (* glMultiTexCoord4svProcPtr) (GLenum target, const GLshort *v); + +typedef void (* glFogCoordfProcPtr) (GLfloat coord); +typedef void (* glFogCoordfvProcPtr) (const GLfloat *coord); +typedef void (* glFogCoorddProcPtr) (GLdouble coord); +typedef void (* glFogCoorddvProcPtr) (const GLdouble *coord); +typedef void (* glFogCoordPointerProcPtr) (GLenum type, GLsizei stride, const GLvoid *pointer); + +typedef void (* glSecondaryColor3bProcPtr) (GLbyte red, GLbyte green, GLbyte blue); +typedef void (* glSecondaryColor3bvProcPtr) (const GLbyte *v); +typedef void (* glSecondaryColor3dProcPtr) (GLdouble red, GLdouble green, GLdouble blue); +typedef void (* glSecondaryColor3dvProcPtr) (const GLdouble *v); +typedef void (* glSecondaryColor3fProcPtr) (GLfloat red, GLfloat green, GLfloat blue); +typedef void (* glSecondaryColor3fvProcPtr) (const GLfloat *v); +typedef void (* glSecondaryColor3iProcPtr) (GLint red, GLint green, GLint blue); +typedef void (* glSecondaryColor3ivProcPtr) (const GLint *v); +typedef void (* glSecondaryColor3sProcPtr) (GLshort red, GLshort green, GLshort blue); +typedef void (* glSecondaryColor3svProcPtr) (const GLshort *v); +typedef void (* glSecondaryColor3ubProcPtr) (GLubyte red, GLubyte green, GLubyte blue); +typedef void (* glSecondaryColor3ubvProcPtr) (const GLubyte *v); +typedef void (* glSecondaryColor3uiProcPtr) (GLuint red, GLuint green, GLuint blue); +typedef void (* glSecondaryColor3uivProcPtr) (const GLuint *v); +typedef void (* glSecondaryColor3usProcPtr) (GLushort red, GLushort green, GLushort blue); +typedef void (* glSecondaryColor3usvProcPtr) (const GLushort *v); +typedef void (* glSecondaryColorPointerProcPtr) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +typedef void (* glPointParameterfProcPtr) (GLenum pname, GLfloat param); +typedef void (* glPointParameterfvProcPtr) (GLenum pname, const GLfloat *params); +typedef void (* glPointParameteriProcPtr) (GLenum pname, GLint param); +typedef void (* glPointParameterivProcPtr) (GLenum pname, const GLint *params); + +typedef void (* glBlendFuncSeparateProcPtr) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +typedef void (* glMultiDrawArraysProcPtr) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (* glMultiDrawElementsProcPtr) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); + +typedef void (* glWindowPos2dProcPtr) (GLdouble x, GLdouble y); +typedef void (* glWindowPos2dvProcPtr) (const GLdouble *v); +typedef void (* glWindowPos2fProcPtr) (GLfloat x, GLfloat y); +typedef void (* glWindowPos2fvProcPtr) (const GLfloat *v); +typedef void (* glWindowPos2iProcPtr) (GLint x, GLint y); +typedef void (* glWindowPos2ivProcPtr) (const GLint *v); +typedef void (* glWindowPos2sProcPtr) (GLshort x, GLshort y); +typedef void (* glWindowPos2svProcPtr) (const GLshort *v); +typedef void (* glWindowPos3dProcPtr) (GLdouble x, GLdouble y, GLdouble z); +typedef void (* glWindowPos3dvProcPtr) (const GLdouble *v); +typedef void (* glWindowPos3fProcPtr) (GLfloat x, GLfloat y, GLfloat z); +typedef void (* glWindowPos3fvProcPtr) (const GLfloat *v); +typedef void (* glWindowPos3iProcPtr) (GLint x, GLint y, GLint z); +typedef void (* glWindowPos3ivProcPtr) (const GLint *v); +typedef void (* glWindowPos3sProcPtr) (GLshort x, GLshort y, GLshort z); +typedef void (* glWindowPos3svProcPtr) (const GLshort *v); + +typedef void (* glGenQueriesProcPtr) (GLsizei n, GLuint *ids); +typedef void (* glDeleteQueriesProcPtr) (GLsizei n, const GLuint *ids); +typedef GLboolean (* glIsQueryProcPtr) (GLuint id); +typedef void (* glBeginQueryProcPtr) (GLenum target, GLuint id); +typedef void (* glEndQueryProcPtr) (GLenum target); +typedef void (* glGetQueryivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetQueryObjectivProcPtr) (GLuint id, GLenum pname, GLint *params); +typedef void (* glGetQueryObjectuivProcPtr) (GLuint id, GLenum pname, GLuint *params); + +typedef void (* glBindBufferProcPtr) (GLenum target, GLuint buffer); +typedef void (* glDeleteBuffersProcPtr) (GLsizei n, const GLuint *buffers); +typedef void (* glGenBuffersProcPtr) (GLsizei n, GLuint *buffers); +typedef GLboolean (* glIsBufferProcPtr) (GLuint buffer); +typedef void (* glBufferDataProcPtr) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +typedef void (* glBufferSubDataProcPtr) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +typedef void (* glGetBufferSubDataProcPtr) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +typedef GLvoid *(* glMapBufferProcPtr) (GLenum target, GLenum access); +typedef GLboolean (* glUnmapBufferProcPtr) (GLenum target); +typedef void (* glGetBufferParameterivProcPtr) (GLenum target, GLenum pname, GLint *params); +typedef void (* glGetBufferPointervProcPtr) (GLenum target, GLenum pname, GLvoid **params); + +typedef void (* glDrawBuffersProcPtr) (GLsizei n, const GLenum *bufs); +typedef void (* glVertexAttrib1dProcPtr) (GLuint index, GLdouble x); +typedef void (* glVertexAttrib1dvProcPtr) (GLuint index, const GLdouble *v); +typedef void (* glVertexAttrib1fProcPtr) (GLuint index, GLfloat x); +typedef void (* glVertexAttrib1fvProcPtr) (GLuint index, const GLfloat *v); +typedef void (* glVertexAttrib1sProcPtr) (GLuint index, GLshort x); +typedef void (* glVertexAttrib1svProcPtr) (GLuint index, const GLshort *v); +typedef void (* glVertexAttrib2dProcPtr) (GLuint index, GLdouble x, GLdouble y); +typedef void (* glVertexAttrib2dvProcPtr) (GLuint index, const GLdouble *v); +typedef void (* glVertexAttrib2fProcPtr) (GLuint index, GLfloat x, GLfloat y); +typedef void (* glVertexAttrib2fvProcPtr) (GLuint index, const GLfloat *v); +typedef void (* glVertexAttrib2sProcPtr) (GLuint index, GLshort x, GLshort y); +typedef void (* glVertexAttrib2svProcPtr) (GLuint index, const GLshort *v); +typedef void (* glVertexAttrib3dProcPtr) (GLuint index, GLdouble x, GLdouble y, GLdouble z); +typedef void (* glVertexAttrib3dvProcPtr) (GLuint index, const GLdouble *v); +typedef void (* glVertexAttrib3fProcPtr) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (* glVertexAttrib3fvProcPtr) (GLuint index, const GLfloat *v); +typedef void (* glVertexAttrib3sProcPtr) (GLuint index, GLshort x, GLshort y, GLshort z); +typedef void (* glVertexAttrib3svProcPtr) (GLuint index, const GLshort *v); +typedef void (* glVertexAttrib4NbvProcPtr) (GLuint index, const GLbyte *v); +typedef void (* glVertexAttrib4NivProcPtr) (GLuint index, const GLint *v); +typedef void (* glVertexAttrib4NsvProcPtr) (GLuint index, const GLshort *v); +typedef void (* glVertexAttrib4NubProcPtr) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +typedef void (* glVertexAttrib4NubvProcPtr) (GLuint index, const GLubyte *v); +typedef void (* glVertexAttrib4NuivProcPtr) (GLuint index, const GLuint *v); +typedef void (* glVertexAttrib4NusvProcPtr) (GLuint index, const GLushort *v); +typedef void (* glVertexAttrib4bvProcPtr) (GLuint index, const GLbyte *v); +typedef void (* glVertexAttrib4dProcPtr) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +typedef void (* glVertexAttrib4dvProcPtr) (GLuint index, const GLdouble *v); +typedef void (* glVertexAttrib4fProcPtr) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (* glVertexAttrib4fvProcPtr) (GLuint index, const GLfloat *v); +typedef void (* glVertexAttrib4ivProcPtr) (GLuint index, const GLint *v); +typedef void (* glVertexAttrib4sProcPtr) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +typedef void (* glVertexAttrib4svProcPtr) (GLuint index, const GLshort *v); +typedef void (* glVertexAttrib4ubvProcPtr) (GLuint index, const GLubyte *v); +typedef void (* glVertexAttrib4uivProcPtr) (GLuint index, const GLuint *v); +typedef void (* glVertexAttrib4usvProcPtr) (GLuint index, const GLushort *v); +typedef void (* glVertexAttribPointerProcPtr) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +typedef void (* glEnableVertexAttribArrayProcPtr) (GLuint index); +typedef void (* glDisableVertexAttribArrayProcPtr) (GLuint index); +typedef void (* glGetVertexAttribdvProcPtr) (GLuint index, GLenum pname, GLdouble *params); +typedef void (* glGetVertexAttribfvProcPtr) (GLuint index, GLenum pname, GLfloat *params); +typedef void (* glGetVertexAttribivProcPtr) (GLuint index, GLenum pname, GLint *params); +typedef void (* glGetVertexAttribPointervProcPtr) (GLuint index, GLenum pname, GLvoid* *pointer); +typedef void (* glDeleteShaderProcPtr) (GLuint shader); +typedef void (* glDetachShaderProcPtr) (GLuint program, GLuint shader); +typedef GLuint (* glCreateShaderProcPtr) (GLenum type); +typedef void (* glShaderSourceProcPtr) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); +typedef void (* glCompileShaderProcPtr) (GLuint shader); +typedef GLuint (* glCreateProgramProcPtr) (void); +typedef void (* glAttachShaderProcPtr) (GLuint program, GLuint shader); +typedef void (* glLinkProgramProcPtr) (GLuint program); +typedef void (* glUseProgramProcPtr) (GLuint program); +typedef void (* glDeleteProgramProcPtr) (GLuint program); +typedef void (* glValidateProgramProcPtr) (GLuint program); +typedef void (* glUniform1fProcPtr) (GLint location, GLfloat v0); +typedef void (* glUniform2fProcPtr) (GLint location, GLfloat v0, GLfloat v1); +typedef void (* glUniform3fProcPtr) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (* glUniform4fProcPtr) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (* glUniform1iProcPtr) (GLint location, GLint v0); +typedef void (* glUniform2iProcPtr) (GLint location, GLint v0, GLint v1); +typedef void (* glUniform3iProcPtr) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (* glUniform4iProcPtr) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (* glUniform1fvProcPtr) (GLint location, GLsizei count, const GLfloat *value); +typedef void (* glUniform2fvProcPtr) (GLint location, GLsizei count, const GLfloat *value); +typedef void (* glUniform3fvProcPtr) (GLint location, GLsizei count, const GLfloat *value); +typedef void (* glUniform4fvProcPtr) (GLint location, GLsizei count, const GLfloat *value); +typedef void (* glUniform1ivProcPtr) (GLint location, GLsizei count, const GLint *value); +typedef void (* glUniform2ivProcPtr) (GLint location, GLsizei count, const GLint *value); +typedef void (* glUniform3ivProcPtr) (GLint location, GLsizei count, const GLint *value); +typedef void (* glUniform4ivProcPtr) (GLint location, GLsizei count, const GLint *value); +typedef void (* glUniformMatrix2fvProcPtr) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (* glUniformMatrix3fvProcPtr) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (* glUniformMatrix4fvProcPtr) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef GLboolean (* glIsShaderProcPtr) (GLuint shader); +typedef GLboolean (* glIsProgramProcPtr) (GLuint program); +typedef void (* glGetShaderivProcPtr) (GLuint shader, GLenum pname, GLint *params); +typedef void (* glGetProgramivProcPtr) (GLuint program, GLenum pname, GLint *params); +typedef void (* glGetAttachedShadersProcPtr) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef void (* glGetShaderInfoLogProcPtr) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (* glGetProgramInfoLogProcPtr) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef GLint (* glGetUniformLocationProcPtr) (GLuint program, const GLchar *name); +typedef void (* glGetActiveUniformProcPtr) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (* glGetUniformfvProcPtr) (GLuint program, GLint location, GLfloat *params); +typedef void (* glGetUniformivProcPtr) (GLuint program, GLint location, GLint *params); +typedef void (* glGetShaderSourceProcPtr) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef void (* glBindAttribLocationProcPtr) (GLuint program, GLuint index, const GLchar *name); +typedef void (* glGetActiveAttribProcPtr) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef GLint (* glGetAttribLocationProcPtr) (GLuint program, const GLchar *name); +typedef void (* glStencilFuncSeparateProcPtr) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (* glStencilOpSeparateProcPtr) (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +typedef void (* glStencilMaskSeparateProcPtr) (GLenum face, GLuint mask); + +#else /* GL_GLEXT_FUNCTION_POINTERS */ + +extern void glAccum (GLenum op, GLfloat value); +extern void glAlphaFunc (GLenum func, GLclampf ref); +extern GLboolean glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); +extern void glArrayElement (GLint i); +extern void glBegin (GLenum mode); +extern void glBindTexture (GLenum target, GLuint texture); +extern void glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +extern void glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +extern void glBlendEquation (GLenum mode); +extern void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); +extern void glBlendFunc (GLenum sfactor, GLenum dfactor); +extern void glCallList (GLuint list); +extern void glCallLists (GLsizei n, GLenum type, const GLvoid *lists); +extern void glClear (GLbitfield mask); +extern void glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +extern void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +extern void glClearDepth (GLclampd depth); +extern void glClearIndex (GLfloat c); +extern void glClearStencil (GLint s); +extern void glClipPlane (GLenum plane, const GLdouble *equation); +extern void glColor3b (GLbyte red, GLbyte green, GLbyte blue); +extern void glColor3bv (const GLbyte *v); +extern void glColor3d (GLdouble red, GLdouble green, GLdouble blue); +extern void glColor3dv (const GLdouble *v); +extern void glColor3f (GLfloat red, GLfloat green, GLfloat blue); +extern void glColor3fv (const GLfloat *v); +extern void glColor3i (GLint red, GLint green, GLint blue); +extern void glColor3iv (const GLint *v); +extern void glColor3s (GLshort red, GLshort green, GLshort blue); +extern void glColor3sv (const GLshort *v); +extern void glColor3ub (GLubyte red, GLubyte green, GLubyte blue); +extern void glColor3ubv (const GLubyte *v); +extern void glColor3ui (GLuint red, GLuint green, GLuint blue); +extern void glColor3uiv (const GLuint *v); +extern void glColor3us (GLushort red, GLushort green, GLushort blue); +extern void glColor3usv (const GLushort *v); +extern void glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +extern void glColor4bv (const GLbyte *v); +extern void glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +extern void glColor4dv (const GLdouble *v); +extern void glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +extern void glColor4fv (const GLfloat *v); +extern void glColor4i (GLint red, GLint green, GLint blue, GLint alpha); +extern void glColor4iv (const GLint *v); +extern void glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); +extern void glColor4sv (const GLshort *v); +extern void glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +extern void glColor4ubv (const GLubyte *v); +extern void glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); +extern void glColor4uiv (const GLuint *v); +extern void glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); +extern void glColor4usv (const GLushort *v); +extern void glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +extern void glColorMaterial (GLenum face, GLenum mode); +extern void glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +extern void glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); +extern void glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); +extern void glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); +extern void glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); +extern void glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); +extern void glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); +extern void glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); +extern void glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); +extern void glConvolutionParameteri (GLenum target, GLenum pname, GLint params); +extern void glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); +extern void glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); +extern void glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +extern void glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); +extern void glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); +extern void glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +extern void glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); +extern void glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +extern void glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +extern void glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +extern void glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +extern void glCullFace (GLenum mode); +extern void glDeleteLists (GLuint list, GLsizei range); +extern void glDeleteTextures (GLsizei n, const GLuint *textures); +extern void glDepthFunc (GLenum func); +extern void glDepthMask (GLboolean flag); +extern void glDepthRange (GLclampd zNear, GLclampd zFar); +extern void glDisable (GLenum cap); +extern void glDisableClientState (GLenum array); +extern void glDrawArrays (GLenum mode, GLint first, GLsizei count); +extern void glDrawBuffer (GLenum mode); +extern void glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +extern void glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +extern void glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); +extern void glEdgeFlag (GLboolean flag); +extern void glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer); +extern void glEdgeFlagv (const GLboolean *flag); +extern void glEnable (GLenum cap); +extern void glEnableClientState (GLenum array); +extern void glEnd (void); +extern void glEndList (void); +extern void glEvalCoord1d (GLdouble u); +extern void glEvalCoord1dv (const GLdouble *u); +extern void glEvalCoord1f (GLfloat u); +extern void glEvalCoord1fv (const GLfloat *u); +extern void glEvalCoord2d (GLdouble u, GLdouble v); +extern void glEvalCoord2dv (const GLdouble *u); +extern void glEvalCoord2f (GLfloat u, GLfloat v); +extern void glEvalCoord2fv (const GLfloat *u); +extern void glEvalMesh1 (GLenum mode, GLint i1, GLint i2); +extern void glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +extern void glEvalPoint1 (GLint i); +extern void glEvalPoint2 (GLint i, GLint j); +extern void glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); +extern void glFinish (void); +extern void glFlush (void); +extern void glFogf (GLenum pname, GLfloat param); +extern void glFogfv (GLenum pname, const GLfloat *params); +extern void glFogi (GLenum pname, GLint param); +extern void glFogiv (GLenum pname, const GLint *params); +extern void glFrontFace (GLenum mode); +extern void glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +extern GLuint glGenLists (GLsizei range); +extern void glGenTextures (GLsizei n, GLuint *textures); +extern void glGetBooleanv (GLenum pname, GLboolean *params); +extern void glGetClipPlane (GLenum plane, GLdouble *equation); +extern void glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table); +extern void glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); +extern void glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); +extern void glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image); +extern void glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); +extern void glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); +extern void glGetDoublev (GLenum pname, GLdouble *params); +extern GLenum glGetError (void); +extern void glGetFloatv (GLenum pname, GLfloat *params); +extern void glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +extern void glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); +extern void glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); +extern void glGetIntegerv (GLenum pname, GLint *params); +extern void glGetLightfv (GLenum light, GLenum pname, GLfloat *params); +extern void glGetLightiv (GLenum light, GLenum pname, GLint *params); +extern void glGetMapdv (GLenum target, GLenum query, GLdouble *v); +extern void glGetMapfv (GLenum target, GLenum query, GLfloat *v); +extern void glGetMapiv (GLenum target, GLenum query, GLint *v); +extern void glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); +extern void glGetMaterialiv (GLenum face, GLenum pname, GLint *params); +extern void glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); +extern void glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); +extern void glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); +extern void glGetPixelMapfv (GLenum map, GLfloat *values); +extern void glGetPixelMapuiv (GLenum map, GLuint *values); +extern void glGetPixelMapusv (GLenum map, GLushort *values); +extern void glGetPointerv (GLenum pname, GLvoid* *params); +extern void glGetPolygonStipple (GLubyte *mask); +extern void glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); +extern const GLubyte * glGetString (GLenum name); +extern void glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); +extern void glGetTexEnviv (GLenum target, GLenum pname, GLint *params); +extern void glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); +extern void glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); +extern void glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); +extern void glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +extern void glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); +extern void glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); +extern void glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +extern void glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +extern void glHint (GLenum target, GLenum mode); +extern void glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); +extern void glIndexMask (GLuint mask); +extern void glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +extern void glIndexd (GLdouble c); +extern void glIndexdv (const GLdouble *c); +extern void glIndexf (GLfloat c); +extern void glIndexfv (const GLfloat *c); +extern void glIndexi (GLint c); +extern void glIndexiv (const GLint *c); +extern void glIndexs (GLshort c); +extern void glIndexsv (const GLshort *c); +extern void glIndexub (GLubyte c); +extern void glIndexubv (const GLubyte *c); +extern void glInitNames (void); +extern void glInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer); +extern GLboolean glIsEnabled (GLenum cap); +extern GLboolean glIsList (GLuint list); +extern GLboolean glIsTexture (GLuint texture); +extern void glLightModelf (GLenum pname, GLfloat param); +extern void glLightModelfv (GLenum pname, const GLfloat *params); +extern void glLightModeli (GLenum pname, GLint param); +extern void glLightModeliv (GLenum pname, const GLint *params); +extern void glLightf (GLenum light, GLenum pname, GLfloat param); +extern void glLightfv (GLenum light, GLenum pname, const GLfloat *params); +extern void glLighti (GLenum light, GLenum pname, GLint param); +extern void glLightiv (GLenum light, GLenum pname, const GLint *params); +extern void glLineStipple (GLint factor, GLushort pattern); +extern void glLineWidth (GLfloat width); +extern void glListBase (GLuint base); +extern void glLoadIdentity (void); +extern void glLoadMatrixd (const GLdouble *m); +extern void glLoadMatrixf (const GLfloat *m); +extern void glLoadName (GLuint name); +extern void glLogicOp (GLenum opcode); +extern void glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +extern void glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +extern void glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +extern void glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +extern void glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); +extern void glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); +extern void glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +extern void glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +extern void glMaterialf (GLenum face, GLenum pname, GLfloat param); +extern void glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); +extern void glMateriali (GLenum face, GLenum pname, GLint param); +extern void glMaterialiv (GLenum face, GLenum pname, const GLint *params); +extern void glMatrixMode (GLenum mode); +extern void glMinmax (GLenum target, GLenum internalformat, GLboolean sink); +extern void glMultMatrixd (const GLdouble *m); +extern void glMultMatrixf (const GLfloat *m); +extern void glNewList (GLuint list, GLenum mode); +extern void glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); +extern void glNormal3bv (const GLbyte *v); +extern void glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); +extern void glNormal3dv (const GLdouble *v); +extern void glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); +extern void glNormal3fv (const GLfloat *v); +extern void glNormal3i (GLint nx, GLint ny, GLint nz); +extern void glNormal3iv (const GLint *v); +extern void glNormal3s (GLshort nx, GLshort ny, GLshort nz); +extern void glNormal3sv (const GLshort *v); +extern void glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer); +extern void glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +extern void glPassThrough (GLfloat token); +extern void glPixelMapfv (GLenum map, GLint mapsize, const GLfloat *values); +extern void glPixelMapuiv (GLenum map, GLint mapsize, const GLuint *values); +extern void glPixelMapusv (GLenum map, GLint mapsize, const GLushort *values); +extern void glPixelStoref (GLenum pname, GLfloat param); +extern void glPixelStorei (GLenum pname, GLint param); +extern void glPixelTransferf (GLenum pname, GLfloat param); +extern void glPixelTransferi (GLenum pname, GLint param); +extern void glPixelZoom (GLfloat xfactor, GLfloat yfactor); +extern void glPointSize (GLfloat size); +extern void glPolygonMode (GLenum face, GLenum mode); +extern void glPolygonOffset (GLfloat factor, GLfloat units); +extern void glPolygonStipple (const GLubyte *mask); +extern void glPopAttrib (void); +extern void glPopClientAttrib (void); +extern void glPopMatrix (void); +extern void glPopName (void); +extern void glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); +extern void glPushAttrib (GLbitfield mask); +extern void glPushClientAttrib (GLbitfield mask); +extern void glPushMatrix (void); +extern void glPushName (GLuint name); +extern void glRasterPos2d (GLdouble x, GLdouble y); +extern void glRasterPos2dv (const GLdouble *v); +extern void glRasterPos2f (GLfloat x, GLfloat y); +extern void glRasterPos2fv (const GLfloat *v); +extern void glRasterPos2i (GLint x, GLint y); +extern void glRasterPos2iv (const GLint *v); +extern void glRasterPos2s (GLshort x, GLshort y); +extern void glRasterPos2sv (const GLshort *v); +extern void glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); +extern void glRasterPos3dv (const GLdouble *v); +extern void glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); +extern void glRasterPos3fv (const GLfloat *v); +extern void glRasterPos3i (GLint x, GLint y, GLint z); +extern void glRasterPos3iv (const GLint *v); +extern void glRasterPos3s (GLshort x, GLshort y, GLshort z); +extern void glRasterPos3sv (const GLshort *v); +extern void glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +extern void glRasterPos4dv (const GLdouble *v); +extern void glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +extern void glRasterPos4fv (const GLfloat *v); +extern void glRasterPos4i (GLint x, GLint y, GLint z, GLint w); +extern void glRasterPos4iv (const GLint *v); +extern void glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); +extern void glRasterPos4sv (const GLshort *v); +extern void glReadBuffer (GLenum mode); +extern void glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +extern void glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +extern void glRectdv (const GLdouble *v1, const GLdouble *v2); +extern void glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +extern void glRectfv (const GLfloat *v1, const GLfloat *v2); +extern void glRecti (GLint x1, GLint y1, GLint x2, GLint y2); +extern void glRectiv (const GLint *v1, const GLint *v2); +extern void glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); +extern void glRectsv (const GLshort *v1, const GLshort *v2); +extern GLint glRenderMode (GLenum mode); +extern void glResetHistogram (GLenum target); +extern void glResetMinmax (GLenum target); +extern void glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +extern void glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +extern void glScaled (GLdouble x, GLdouble y, GLdouble z); +extern void glScalef (GLfloat x, GLfloat y, GLfloat z); +extern void glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +extern void glSelectBuffer (GLsizei size, GLuint *buffer); +extern void glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); +extern void glShadeModel (GLenum mode); +extern void glStencilFunc (GLenum func, GLint ref, GLuint mask); +extern void glStencilMask (GLuint mask); +extern void glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +extern void glTexCoord1d (GLdouble s); +extern void glTexCoord1dv (const GLdouble *v); +extern void glTexCoord1f (GLfloat s); +extern void glTexCoord1fv (const GLfloat *v); +extern void glTexCoord1i (GLint s); +extern void glTexCoord1iv (const GLint *v); +extern void glTexCoord1s (GLshort s); +extern void glTexCoord1sv (const GLshort *v); +extern void glTexCoord2d (GLdouble s, GLdouble t); +extern void glTexCoord2dv (const GLdouble *v); +extern void glTexCoord2f (GLfloat s, GLfloat t); +extern void glTexCoord2fv (const GLfloat *v); +extern void glTexCoord2i (GLint s, GLint t); +extern void glTexCoord2iv (const GLint *v); +extern void glTexCoord2s (GLshort s, GLshort t); +extern void glTexCoord2sv (const GLshort *v); +extern void glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); +extern void glTexCoord3dv (const GLdouble *v); +extern void glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); +extern void glTexCoord3fv (const GLfloat *v); +extern void glTexCoord3i (GLint s, GLint t, GLint r); +extern void glTexCoord3iv (const GLint *v); +extern void glTexCoord3s (GLshort s, GLshort t, GLshort r); +extern void glTexCoord3sv (const GLshort *v); +extern void glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); +extern void glTexCoord4dv (const GLdouble *v); +extern void glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); +extern void glTexCoord4fv (const GLfloat *v); +extern void glTexCoord4i (GLint s, GLint t, GLint r, GLint q); +extern void glTexCoord4iv (const GLint *v); +extern void glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); +extern void glTexCoord4sv (const GLshort *v); +extern void glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +extern void glTexEnvf (GLenum target, GLenum pname, GLfloat param); +extern void glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); +extern void glTexEnvi (GLenum target, GLenum pname, GLint param); +extern void glTexEnviv (GLenum target, GLenum pname, const GLint *params); +extern void glTexGend (GLenum coord, GLenum pname, GLdouble param); +extern void glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); +extern void glTexGenf (GLenum coord, GLenum pname, GLfloat param); +extern void glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); +extern void glTexGeni (GLenum coord, GLenum pname, GLint param); +extern void glTexGeniv (GLenum coord, GLenum pname, const GLint *params); +extern void glTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +extern void glTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +extern void glTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +extern void glTexParameterf (GLenum target, GLenum pname, GLfloat param); +extern void glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +extern void glTexParameteri (GLenum target, GLenum pname, GLint param); +extern void glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +extern void glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +extern void glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +extern void glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); +extern void glTranslated (GLdouble x, GLdouble y, GLdouble z); +extern void glTranslatef (GLfloat x, GLfloat y, GLfloat z); +extern void glVertex2d (GLdouble x, GLdouble y); +extern void glVertex2dv (const GLdouble *v); +extern void glVertex2f (GLfloat x, GLfloat y); +extern void glVertex2fv (const GLfloat *v); +extern void glVertex2i (GLint x, GLint y); +extern void glVertex2iv (const GLint *v); +extern void glVertex2s (GLshort x, GLshort y); +extern void glVertex2sv (const GLshort *v); +extern void glVertex3d (GLdouble x, GLdouble y, GLdouble z); +extern void glVertex3dv (const GLdouble *v); +extern void glVertex3f (GLfloat x, GLfloat y, GLfloat z); +extern void glVertex3fv (const GLfloat *v); +extern void glVertex3i (GLint x, GLint y, GLint z); +extern void glVertex3iv (const GLint *v); +extern void glVertex3s (GLshort x, GLshort y, GLshort z); +extern void glVertex3sv (const GLshort *v); +extern void glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); +extern void glVertex4dv (const GLdouble *v); +extern void glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); +extern void glVertex4fv (const GLfloat *v); +extern void glVertex4i (GLint x, GLint y, GLint z, GLint w); +extern void glVertex4iv (const GLint *v); +extern void glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); +extern void glVertex4sv (const GLshort *v); +extern void glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +extern void glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +extern void glSampleCoverage (GLclampf value, GLboolean invert); +extern void glSamplePass (GLenum pass); + +extern void glLoadTransposeMatrixf (const GLfloat *m); +extern void glLoadTransposeMatrixd (const GLdouble *m); +extern void glMultTransposeMatrixf (const GLfloat *m); +extern void glMultTransposeMatrixd (const GLdouble *m); + +extern void glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); +extern void glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +extern void glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); +extern void glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); +extern void glGetCompressedTexImage (GLenum target, GLint lod, GLvoid *img); + +extern void glActiveTexture (GLenum texture); +extern void glClientActiveTexture (GLenum texture); +extern void glMultiTexCoord1d (GLenum target, GLdouble s); +extern void glMultiTexCoord1dv (GLenum target, const GLdouble *v); +extern void glMultiTexCoord1f (GLenum target, GLfloat s); +extern void glMultiTexCoord1fv (GLenum target, const GLfloat *v); +extern void glMultiTexCoord1i (GLenum target, GLint s); +extern void glMultiTexCoord1iv (GLenum target, const GLint *v); +extern void glMultiTexCoord1s (GLenum target, GLshort s); +extern void glMultiTexCoord1sv (GLenum target, const GLshort *v); +extern void glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); +extern void glMultiTexCoord2dv (GLenum target, const GLdouble *v); +extern void glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); +extern void glMultiTexCoord2fv (GLenum target, const GLfloat *v); +extern void glMultiTexCoord2i (GLenum target, GLint s, GLint t); +extern void glMultiTexCoord2iv (GLenum target, const GLint *v); +extern void glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); +extern void glMultiTexCoord2sv (GLenum target, const GLshort *v); +extern void glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); +extern void glMultiTexCoord3dv (GLenum target, const GLdouble *v); +extern void glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); +extern void glMultiTexCoord3fv (GLenum target, const GLfloat *v); +extern void glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); +extern void glMultiTexCoord3iv (GLenum target, const GLint *v); +extern void glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); +extern void glMultiTexCoord3sv (GLenum target, const GLshort *v); +extern void glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); +extern void glMultiTexCoord4dv (GLenum target, const GLdouble *v); +extern void glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); +extern void glMultiTexCoord4fv (GLenum target, const GLfloat *v); +extern void glMultiTexCoord4i (GLenum target, GLint, GLint s, GLint t, GLint r); +extern void glMultiTexCoord4iv (GLenum target, const GLint *v); +extern void glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); +extern void glMultiTexCoord4sv (GLenum target, const GLshort *v); + +extern void glFogCoordf (GLfloat coord); +extern void glFogCoordfv (const GLfloat *coord); +extern void glFogCoordd (GLdouble coord); +extern void glFogCoorddv (const GLdouble * coord); +extern void glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer); + +extern void glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); +extern void glSecondaryColor3bv (const GLbyte *v); +extern void glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); +extern void glSecondaryColor3dv (const GLdouble *v); +extern void glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); +extern void glSecondaryColor3fv (const GLfloat *v); +extern void glSecondaryColor3i (GLint red, GLint green, GLint blue); +extern void glSecondaryColor3iv (const GLint *v); +extern void glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); +extern void glSecondaryColor3sv (const GLshort *v); +extern void glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); +extern void glSecondaryColor3ubv (const GLubyte *v); +extern void glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); +extern void glSecondaryColor3uiv (const GLuint *v); +extern void glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); +extern void glSecondaryColor3usv (const GLushort *v); +extern void glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + +extern void glPointParameterf (GLenum pname, GLfloat param); +extern void glPointParameterfv (GLenum pname, const GLfloat *params); +extern void glPointParameteri (GLenum pname, GLint param); +extern void glPointParameteriv (GLenum pname, const GLint *params); + +extern void glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +extern void glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +extern void glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); + +extern void glWindowPos2d (GLdouble x, GLdouble y); +extern void glWindowPos2dv (const GLdouble *v); +extern void glWindowPos2f (GLfloat x, GLfloat y); +extern void glWindowPos2fv (const GLfloat *v); +extern void glWindowPos2i (GLint x, GLint y); +extern void glWindowPos2iv (const GLint *v); +extern void glWindowPos2s (GLshort x, GLshort y); +extern void glWindowPos2sv (const GLshort *v); +extern void glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); +extern void glWindowPos3dv (const GLdouble *v); +extern void glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); +extern void glWindowPos3fv (const GLfloat *v); +extern void glWindowPos3i (GLint x, GLint y, GLint z); +extern void glWindowPos3iv (const GLint *v); +extern void glWindowPos3s (GLshort x, GLshort y, GLshort z); +extern void glWindowPos3sv (const GLshort *v); + +extern void glGenQueries(GLsizei n, GLuint *ids); +extern void glDeleteQueries(GLsizei n, const GLuint *ids); +extern GLboolean glIsQuery(GLuint id); +extern void glBeginQuery(GLenum target, GLuint id); +extern void glEndQuery(GLenum target); +extern void glGetQueryiv(GLenum target, GLenum pname, GLint *params); +extern void glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params); +extern void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); + +extern void glBindBuffer (GLenum target, GLuint buffer); +extern void glDeleteBuffers (GLsizei n, const GLuint *buffers); +extern void glGenBuffers (GLsizei n, GLuint *buffers); +extern GLboolean glIsBuffer (GLuint buffer); +extern void glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); +extern void glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); +extern void glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); +extern GLvoid * glMapBuffer (GLenum target, GLenum access); +extern GLboolean glUnmapBuffer (GLenum target); +extern void glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +extern void glGetBufferPointerv (GLenum target, GLenum pname, GLvoid **params); + +extern void glDrawBuffers (GLsizei n, const GLenum *bufs); +extern void glVertexAttrib1d (GLuint index, GLdouble x); +extern void glVertexAttrib1dv (GLuint index, const GLdouble *v); +extern void glVertexAttrib1f (GLuint index, GLfloat x); +extern void glVertexAttrib1fv (GLuint index, const GLfloat *v); +extern void glVertexAttrib1s (GLuint index, GLshort x); +extern void glVertexAttrib1sv (GLuint index, const GLshort *v); +extern void glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); +extern void glVertexAttrib2dv (GLuint index, const GLdouble *v); +extern void glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +extern void glVertexAttrib2fv (GLuint index, const GLfloat *v); +extern void glVertexAttrib2s (GLuint index, GLshort x, GLshort y); +extern void glVertexAttrib2sv (GLuint index, const GLshort *v); +extern void glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); +extern void glVertexAttrib3dv (GLuint index, const GLdouble *v); +extern void glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +extern void glVertexAttrib3fv (GLuint index, const GLfloat *v); +extern void glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); +extern void glVertexAttrib3sv (GLuint index, const GLshort *v); +extern void glVertexAttrib4Nbv (GLuint index, const GLbyte *v); +extern void glVertexAttrib4Niv (GLuint index, const GLint *v); +extern void glVertexAttrib4Nsv (GLuint index, const GLshort *v); +extern void glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); +extern void glVertexAttrib4Nubv (GLuint index, const GLubyte *v); +extern void glVertexAttrib4Nuiv (GLuint index, const GLuint *v); +extern void glVertexAttrib4Nusv (GLuint index, const GLushort *v); +extern void glVertexAttrib4bv (GLuint index, const GLbyte *v); +extern void glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +extern void glVertexAttrib4dv (GLuint index, const GLdouble *v); +extern void glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +extern void glVertexAttrib4fv (GLuint index, const GLfloat *v); +extern void glVertexAttrib4iv (GLuint index, const GLint *v); +extern void glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); +extern void glVertexAttrib4sv (GLuint index, const GLshort *v); +extern void glVertexAttrib4ubv (GLuint index, const GLubyte *v); +extern void glVertexAttrib4uiv (GLuint index, const GLuint *v); +extern void glVertexAttrib4usv (GLuint index, const GLushort *v); +extern void glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); +extern void glEnableVertexAttribArray (GLuint index); +extern void glDisableVertexAttribArray (GLuint index); +extern void glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); +extern void glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +extern void glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +extern void glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer); +extern void glDeleteShader (GLuint shader); +extern void glDetachShader (GLuint program, GLuint shader); +extern GLuint glCreateShader (GLenum type); +extern void glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); +extern void glCompileShader (GLuint shader); +extern GLuint glCreateProgram (void); +extern void glAttachShader (GLuint program, GLuint shader); +extern void glLinkProgram (GLuint program); +extern void glUseProgram (GLuint program); +extern void glDeleteProgram (GLuint program); +extern void glValidateProgram (GLuint program); +extern void glUniform1f (GLint location, GLfloat v0); +extern void glUniform2f (GLint location, GLfloat v0, GLfloat v1); +extern void glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +extern void glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +extern void glUniform1i (GLint location, GLint v0); +extern void glUniform2i (GLint location, GLint v0, GLint v1); +extern void glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +extern void glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +extern void glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +extern void glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +extern void glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +extern void glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +extern void glUniform1iv (GLint location, GLsizei count, const GLint *value); +extern void glUniform2iv (GLint location, GLsizei count, const GLint *value); +extern void glUniform3iv (GLint location, GLsizei count, const GLint *value); +extern void glUniform4iv (GLint location, GLsizei count, const GLint *value); +extern void glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern void glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +extern GLboolean glIsShader (GLuint shader); +extern GLboolean glIsProgram (GLuint program); +extern void glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +extern void glGetProgramiv (GLuint program, GLenum pname, GLint *params); +extern void glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +extern void glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +extern void glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +extern GLint glGetUniformLocation (GLuint program, const GLchar *name); +extern void glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +extern void glGetUniformfv (GLuint program, GLint location, GLfloat *params); +extern void glGetUniformiv (GLuint program, GLint location, GLint *params); +extern void glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +extern void glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +extern void glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +extern GLint glGetAttribLocation (GLuint program, const GLchar *name); +extern void glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +extern void glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +extern void glStencilMaskSeparate (GLenum face, GLuint mask); + + +#endif /* GL_GLEXT_FUNCTION_POINTERS */ + +#ifdef __cplusplus +} +#endif + +#endif /* __gl_h_ */ diff --git a/archive/hge/graphics.cpp b/archive/hge/graphics.cpp new file mode 100644 index 0000000..6ee9578 --- /dev/null +++ b/archive/hge/graphics.cpp @@ -0,0 +1,1524 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: graphics +*/ + +// !!! FIXME: the texture data when locking/unlocking textures is in GL_BGRA format, not GL_RGBA. +// !!! FIXME: ...but this mistake wasn't noticed for several games, since most didn't lock outside +// !!! FIXME: of a piece of code that was #ifdef'd for Unix anyhow. +// !!! FIXME: But if you lock textures and the colors are wrong, that's what happened. We need to +// !!! FIXME: sort out all the places where we're passing things around in RGBA to fix this. +// !!! FIXME: In the mean time, it's usually easier to just change your application to expect +// !!! FIXME: locked textures to be RGBA instead of BGRA. + +// !!! FIXME: ...apparently we're locking textures upside down, too? + +#include "hge_impl.h" + +#define SUPPORT_CXIMAGE 1 +#if SUPPORT_CXIMAGE +// conflict with Mac OS X 10.3.9 SDK... +#ifdef _T +#undef _T +#endif +#include "CxImage/ximage.h" +#else +/* Use DevIL instead of CXImage */ +#include <IL/il.h> +#include <IL/ilu.h> +#endif + +// avoiding glext.h here ... +#ifndef GL_TEXTURE_RECTANGLE_ARB +#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 +#endif +#ifndef GL_FRAMEBUFFER_EXT +#define GL_FRAMEBUFFER_EXT 0x8D40 +#endif +#ifndef GL_RENDERBUFFER_EXT +#define GL_RENDERBUFFER_EXT 0x8D41 +#endif +#ifndef GL_COLOR_ATTACHMENT0_EXT +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#endif +#ifndef GL_DEPTH_ATTACHMENT_EXT +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#endif +#ifndef GL_FRAMEBUFFER_COMPLETE_EXT +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#endif +#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif +#ifndef GL_YCBCR_422_APPLE +#define GL_YCBCR_422_APPLE 0x85B9 +#endif +#ifndef GL_UNSIGNED_SHORT_8_8_APPLE +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#endif +#ifndef GL_UNSIGNED_SHORT_8_8_REV_APPLE +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif +static const char* GRAPHICS_SRC_FN="hge/graphics.cpp"; +struct gltexture +{ + GLuint name; + GLuint width; + GLuint height; + GLuint potw; // Power-of-two width. + GLuint poth; // Power-of-two height. + const char *filename; // if backed by a file, not a managed buffer. + DWORD *pixels; // original rgba data. + DWORD *lock_pixels; // for locked texture + bool is_render_target; + bool lost; + bool lock_readonly; + GLint lock_x; + GLint lock_y; + GLint lock_width; + GLint lock_height; +}; + +static DWORD *_DecodeImage(BYTE *data, const char *fname, DWORD size, int &width, int &height) +{ + width = height = 0; + + DWORD *pixels = NULL; + const size_t fnamelen = fname ? strlen(fname) : 0; + if ( (fnamelen > 5) && (strcasecmp((fname + fnamelen) - 5, ".rgba") == 0) ) + { + DWORD *ptr = (DWORD *) data; + DWORD w = ptr[0]; + DWORD h = ptr[1]; + BYTESWAP(w); + BYTESWAP(h); + if ( ((w * h * 4) + 8) == size ) // not truncated? + { + width = (int) w; + height = (int) h; + pixels = new DWORD[width * height]; + memcpy(pixels, ptr + 2, w * h * 4); // !!! FIXME: ignores pitch. + } + return pixels; + } + +#if SUPPORT_CXIMAGE + CxImage img; + img.Decode(data, size, CXIMAGE_FORMAT_UNKNOWN); + if (img.IsValid()) + { + width = img.GetWidth(); + height = img.GetHeight(); + pixels = new DWORD[width * height]; + BYTE *wptr = (BYTE *) pixels; + const bool hasalpha = img.AlphaIsValid(); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + const RGBQUAD rgb = img.GetPixelColor(x, y, true); + *(wptr++) = rgb.rgbRed; + *(wptr++) = rgb.rgbGreen; + *(wptr++) = rgb.rgbBlue; + *(wptr++) = hasalpha ? rgb.rgbReserved : 0xFF; // alpha. + } + } + } +#else + ilInit(); + iluInit(); + + ILuint id; + ilGenImages(1, &id); + + if(ilLoadImage(fname)) { + printf("success: %s\n", fname); + ILinfo info; + iluGetImageInfo(&info); + width = info.Width; + height = info.Height; + size = info.SizeOfData; + pixels = new DWORD[width * height]; + ilCopyPixels(0, 0, 0, width, height, 0, IL_RGBA, IL_UNSIGNED_INT, pixels); + ilShutDown(); + } +#endif + + return pixels; +} + + +void HGE_Impl::_BindTexture(gltexture *t) +{ + // The Direct3D renderer is using managed textures, so they aren't every + // actually "lost" ... we may have to rebuild them here, though. + if ((t != NULL) && (t->lost)) + _ConfigureTexture(t, t->width, t->height, t->pixels); + + if ( ((HTEXTURE)t) != CurTexture ) + { + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, t ? t->name : 0); + CurTexture = (HTEXTURE) t; + } +} + +void CALL HGE_Impl::Gfx_Clear(DWORD color) +{ + GLbitfield flags = GL_COLOR_BUFFER_BIT; + if ( ((pCurTarget) && (pCurTarget->depth)) || bZBuffer ) + flags |= GL_DEPTH_BUFFER_BIT; + + const GLfloat a = ((GLfloat) ((color >> 24) & 0xFF)) / 255.0f; + const GLfloat r = ((GLfloat) ((color >> 16) & 0xFF)) / 255.0f; + const GLfloat g = ((GLfloat) ((color >> 8) & 0xFF)) / 255.0f; + const GLfloat b = ((GLfloat) ((color >> 0) & 0xFF)) / 255.0f; + pOpenGLDevice->glClearColor(r, g, b, a); + pOpenGLDevice->glClear(flags); +} + +void CALL HGE_Impl::Gfx_SetClipping(int x, int y, int w, int h) +{ + int scr_width, scr_height; + struct { int X; int Y; int Width; int Height; float MinZ; float MaxZ; } vp; + + if(!pCurTarget) { + scr_width=pHGE->System_GetStateInt(HGE_SCREENWIDTH); + scr_height=pHGE->System_GetStateInt(HGE_SCREENHEIGHT); + } + else { + scr_width=Texture_GetWidth(pCurTarget->tex); + scr_height=Texture_GetHeight(pCurTarget->tex); + } + + if(!w) { + vp.X=0; + vp.Y=0; + vp.Width=scr_width; + vp.Height=scr_height; + } + else + { + if(x<0) { w+=x; x=0; } + if(y<0) { h+=y; y=0; } + + if(x+w > scr_width) w=scr_width-x; + if(y+h > scr_height) h=scr_height-y; + + vp.X=x; + vp.Y=y; + vp.Width=w; + vp.Height=h; + } + + if ((clipX == vp.X) && (clipY == vp.Y) && (clipW == vp.Width) && (clipH == vp.Height)) + return; // nothing to do here, don't call into the GL. + + vp.MinZ=0.0f; + vp.MaxZ=1.0f; + + _render_batch(); + + clipX = vp.X; + clipY = vp.Y; + clipW = vp.Width; + clipH = vp.Height; + pOpenGLDevice->glScissor(vp.X, (scr_height-vp.Y)-vp.Height, vp.Width, vp.Height); +} + +void CALL HGE_Impl::Gfx_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale) +{ + if ((x == 0.0f) && (y == 0.0f) && (dx == 0.0f) && (dy == 0.0f) && (rot == 0.0f) && (hscale == 0.0f) && (vscale == 0.0f)) + { + //reset everything + pOpenGLDevice->glMatrixMode(GL_MODELVIEW); + pOpenGLDevice->glLoadIdentity(); + bTransforming=false; + return; + } + + _render_batch(); + bTransforming = true; + + pOpenGLDevice->glMatrixMode(GL_MODELVIEW); + //we have to reset the matrix in all cases. + //or this would cause insane transforming... + pOpenGLDevice->glLoadIdentity(); + pOpenGLDevice->glTranslatef(-x, -y, 0.0f); + pOpenGLDevice->glScalef(hscale, vscale, 1.0f); + pOpenGLDevice->glRotatef(rot, 0.0f, 0.0f, 1.0f); + pOpenGLDevice->glTranslatef(x+dx, y+dy, 0.0f); +} + +bool CALL HGE_Impl::Gfx_BeginScene(HTARGET targ) +{ + CRenderTargetList *target=(CRenderTargetList *)targ; + + if(VertArray) + { + _PostError("Gfx_BeginScene: Scene is already being rendered"); + return false; + } + + if(target != pCurTarget) + { + if (pOpenGLDevice->have_GL_EXT_framebuffer_object) + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (target) ? target->frame : 0); + + if ( ((target) && (target->depth)) || (bZBuffer) ) + pOpenGLDevice->glEnable(GL_DEPTH_TEST); + else + pOpenGLDevice->glDisable(GL_DEPTH_TEST); + + // d3d's SetRenderTarget() forces the viewport to surface size... + if (target) + { + pOpenGLDevice->glScissor(0, 0, target->width, target->height); + pOpenGLDevice->glViewport(0, 0, target->width, target->height); + _SetProjectionMatrix(target->width, target->height); + } + else + { + pOpenGLDevice->glScissor(0, 0, nScreenWidth, nScreenHeight); + pOpenGLDevice->glViewport(0, 0, nScreenWidth, nScreenHeight); + _SetProjectionMatrix(nScreenWidth, nScreenHeight); + } + + pOpenGLDevice->glMatrixMode(GL_MODELVIEW); + pOpenGLDevice->glLoadIdentity(); + + pCurTarget=target; + } + + VertArray = pVB; + return true; +} + +void CALL HGE_Impl::Gfx_EndScene() +{ + _render_batch(true); + + // no "real" render targets? Push the framebuffer to a texture. + // This is not going to work in lots of legitimate scenarios, but it will + // most of the time, so it's better than nothing when you lack FBOs. + if ((pCurTarget) && (!pOpenGLDevice->have_GL_EXT_framebuffer_object)) + { + gltexture *pTex = (gltexture *) pCurTarget->tex; + if ((pTex != NULL) && (pTex->lost)) + _ConfigureTexture(pTex, pTex->width, pTex->height, pTex->pixels); + + const int width = pCurTarget->width; + const int height = pCurTarget->height; + pOpenGLDevice->glFinish(); + DWORD *pixels = new DWORD[width * height]; + pOpenGLDevice->glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, pTex->name); + pOpenGLDevice->glTexSubImage2D(pOpenGLDevice->TextureTarget, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, CurTexture ? (((gltexture *) CurTexture)->name) : 0); + delete[] pixels; + } + + if(!pCurTarget) SDL_GL_SwapBuffers(); + //const GLenum err = pOpenGLDevice->glGetError(); + //if (err != GL_NO_ERROR) printf("GL error! 0x%X\n", (int) err); + //Gfx_Clear(0xFF | (0xFF<<24) | (random() & 0xFF << 16) | (random() & 0xFF << 8)); + //Gfx_Clear(0xFF000000); +} + +void HGE_Impl::_SetTextureFilter() +{ + const GLenum filter = (bTextureFilter) ? GL_LINEAR : GL_NEAREST; + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_MIN_FILTER, filter); + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_MAG_FILTER, filter); +} + + +bool HGE_Impl::_PrimsOutsideClipping(const hgeVertex *v, const int verts) +{ + if (bTransforming) + return false; // screw it, let the GL do the clipping. + + const int maxX = clipX + clipW; + const int maxY = clipY + clipH; + for (int i = 0; i < verts; i++, v++) + { + const int x = v->x; + const int y = v->y; + if ((x > clipX) && (x < maxX) && (y > clipY) && (y < maxY)) + return false; + } + return true; +} + + +void CALL HGE_Impl::Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color, float z) +{ + if (VertArray) + { + if(CurPrimType!=HGEPRIM_LINES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_LINES || CurTexture || CurBlendMode!=BLEND_DEFAULT) + { + _render_batch(); + + CurPrimType=HGEPRIM_LINES; + if(CurBlendMode != BLEND_DEFAULT) _SetBlendMode(BLEND_DEFAULT); + _BindTexture(NULL); + } + + int i=nPrim*HGEPRIM_LINES; + VertArray[i].x = x1; VertArray[i+1].x = x2; + VertArray[i].y = y1; VertArray[i+1].y = y2; + VertArray[i].z = VertArray[i+1].z = z; + VertArray[i].col = VertArray[i+1].col = color; + VertArray[i].tx = VertArray[i+1].tx = + VertArray[i].ty = VertArray[i+1].ty = 0.0f; + + if (!_PrimsOutsideClipping(&VertArray[i], HGEPRIM_LINES)) + nPrim++; + } +} + +template <class T> static inline const T Min(const T a, const T b) { return a < b ? a : b; } +template <class T> static inline const T Max(const T a, const T b) { return a > b ? a : b; } + +void CALL HGE_Impl::Gfx_RenderTriple(const hgeTriple *triple) +{ + if (VertArray) + { + const hgeVertex *v = triple->v; + if (_PrimsOutsideClipping(v, HGEPRIM_TRIPLES)) + { + // check for overlap, despite triangle points being outside clipping... + const int maxX = clipX + clipW; + const int maxY = clipY + clipH; + const int leftmost = Min(Min(v[0].x, v[1].x), v[2].x); + const int rightmost = Max(Max(v[0].x, v[1].x), v[2].x); + const int topmost = Min(Min(v[0].y, v[1].y), v[2].y); + const int bottommost = Max(Max(v[0].y, v[1].y), v[2].y); + if ( ((clipX < leftmost) || (clipX > rightmost)) && + ((maxX < leftmost) || (maxX > rightmost)) && + ((clipY < topmost) || (clipY > bottommost)) && + ((maxY < topmost) || (maxY > bottommost)) ) + return; // no, this is really totally clipped. + } + + if(CurPrimType!=HGEPRIM_TRIPLES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_TRIPLES || CurTexture!=triple->tex || CurBlendMode!=triple->blend) + { + _render_batch(); + + CurPrimType=HGEPRIM_TRIPLES; + if(CurBlendMode != triple->blend) _SetBlendMode(triple->blend); + _BindTexture((gltexture *) triple->tex); + } + + memcpy(&VertArray[nPrim*HGEPRIM_TRIPLES], triple->v, sizeof(hgeVertex)*HGEPRIM_TRIPLES); + nPrim++; + } +} + +void CALL HGE_Impl::Gfx_RenderQuad(const hgeQuad *quad) +{ + if (VertArray) + { + const hgeVertex *v = quad->v; + if (_PrimsOutsideClipping(v, HGEPRIM_QUADS)) + { + // check for overlap, despite quad points being outside clipping... + const int maxX = clipX + clipW; + const int maxY = clipY + clipH; + const int leftmost = Min(Min(Min(v[0].x, v[1].x), v[2].x), v[3].x); + const int rightmost = Max(Max(Max(v[0].x, v[1].x), v[2].x), v[3].x); + const int topmost = Min(Min(Min(v[0].y, v[1].y), v[2].y), v[3].y); + const int bottommost = Max(Max(Max(v[0].y, v[1].y), v[2].y), v[3].y); + if ( ((clipX < leftmost) || (clipX > rightmost)) && + ((maxX < leftmost) || (maxX > rightmost)) && + ((clipY < topmost) || (clipY > bottommost)) && + ((maxY < topmost) || (maxY > bottommost)) ) + return; // no, this is really totally clipped. + } + + if(CurPrimType!=HGEPRIM_QUADS || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_QUADS || CurTexture!=quad->tex || CurBlendMode!=quad->blend) + { + _render_batch(); + + CurPrimType=HGEPRIM_QUADS; + if(CurBlendMode != quad->blend) _SetBlendMode(quad->blend); + _BindTexture((gltexture *) quad->tex); + } + + memcpy(&VertArray[nPrim*HGEPRIM_QUADS], quad->v, sizeof(hgeVertex)*HGEPRIM_QUADS); + nPrim++; + } +} + +hgeVertex* CALL HGE_Impl::Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim) +{ + if(VertArray) + { + _render_batch(); + + CurPrimType=prim_type; + if(CurBlendMode != blend) _SetBlendMode(blend); + _BindTexture((gltexture *) tex); + *max_prim=VERTEX_BUFFER_SIZE / prim_type; + return VertArray; + } + else return 0; +} + +void CALL HGE_Impl::Gfx_FinishBatch(int nprim) +{ + nPrim = nprim; +} + +bool HGE_Impl::_BuildTarget(CRenderTargetList *pTarget, GLuint texname, int width, int height, bool zbuffer) +{ + bool okay = true; // no FBOs? Fake success by default. + if (pOpenGLDevice->have_GL_EXT_framebuffer_object) + { + pOpenGLDevice->glGenFramebuffersEXT(1, &pTarget->frame); + if (zbuffer) + pOpenGLDevice->glGenRenderbuffersEXT(1, &pTarget->depth); + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pTarget->frame); + pOpenGLDevice->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, pOpenGLDevice->TextureTarget, texname, 0); + if (zbuffer) + { + pOpenGLDevice->glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pTarget->depth); + pOpenGLDevice->glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height); + pOpenGLDevice->glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, pTarget->depth); + } + + GLenum rc = pOpenGLDevice->glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if ((rc == GL_FRAMEBUFFER_COMPLETE_EXT) && (pOpenGLDevice->glGetError() == GL_NO_ERROR)) + { + pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + okay = true; + } + else + { + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + pOpenGLDevice->glDeleteRenderbuffersEXT(1, &pTarget->depth); + pOpenGLDevice->glDeleteFramebuffersEXT(1, &pTarget->frame); + } + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pCurTarget ? pCurTarget->frame : 0); + } + + return okay; +} + +HTARGET CALL HGE_Impl::Target_Create(int width, int height, bool zbuffer) +{ + bool okay = false; + CRenderTargetList *pTarget = new CRenderTargetList; + memset(pTarget, '\0', sizeof (CRenderTargetList)); + + pTarget->tex = _BuildTexture(width, height, NULL); + gltexture *gltex = (gltexture *) pTarget->tex; + gltex->is_render_target = true; + gltex->lost = false; + _ConfigureTexture(gltex, width, height, NULL); + + pTarget->width = width; + pTarget->height = height; + + okay = _BuildTarget(pTarget, gltex->name, width, height, zbuffer); + if (!okay) + { + System_Log("%s: OpenGL: Failed to create render target!",GRAPHICS_SRC_FN); + Texture_Free(pTarget->tex); + delete pTarget; + return 0; + } + + pTarget->next=pTargets; + pTargets=pTarget; + + return (HTARGET)pTarget; +} + +void CALL HGE_Impl::Target_Free(HTARGET target) +{ + CRenderTargetList *pTarget=pTargets, *pPrevTarget=NULL; + + while(pTarget) + { + if((CRenderTargetList *)target == pTarget) + { + if(pPrevTarget) + pPrevTarget->next = pTarget->next; + else + pTargets = pTarget->next; + + if (pOpenGLDevice->have_GL_EXT_framebuffer_object) + { + if (pCurTarget == (CRenderTargetList *)target) + pOpenGLDevice->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + if (pTarget->depth) + pOpenGLDevice->glDeleteRenderbuffersEXT(1, &pTarget->depth); + pOpenGLDevice->glDeleteFramebuffersEXT(1, &pTarget->frame); + } + + if (pCurTarget == (CRenderTargetList *)target) + pCurTarget = 0; + + Texture_Free(pTarget->tex); + delete pTarget; + return; + } + + pPrevTarget = pTarget; + pTarget = pTarget->next; + } +} + +HTEXTURE CALL HGE_Impl::Target_GetTexture(HTARGET target) +{ + CRenderTargetList *targ=(CRenderTargetList *)target; + if(target) return targ->tex; + else return 0; +} + +static inline bool _IsPowerOfTwo(const GLuint x) +{ + return ((x & (x - 1)) == 0); +} + +static inline GLuint _NextPowerOfTwo(GLuint x) +{ + x--; + for (unsigned i = 1; i < (sizeof(GLuint) * 8); i <<= 1) + x |= x >> i; + return x + 1; +} + +void HGE_Impl::_ConfigureTexture(gltexture *t, int width, int height, DWORD *pixels) +{ + GLuint tex = 0; + pOpenGLDevice->glGenTextures(1, &tex); + + t->lost = false; + t->name = tex; + t->width = width; + t->height = height; + t->pixels = pixels; + t->potw = 0; + t->poth = 0; + + // see if we're backed by a file and not RAM. + const bool loadFromFile = ((pixels == NULL) && (t->filename != NULL)); + if (loadFromFile) + { + DWORD size = 0; + BYTE *data = (BYTE *) pHGE->Resource_Load(t->filename, &size); + if (data != NULL) + { + int w, h; + pixels = _DecodeImage(data, t->filename, size, w, h); + if ((w != width) || (h != height)) // yikes, file changed? + { + delete[] pixels; + pixels = NULL; + } + Resource_Free(data); + } + } + + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, tex); + if (pOpenGLDevice->TextureTarget != GL_TEXTURE_RECTANGLE_ARB) + { + pOpenGLDevice->glTexParameterf(pOpenGLDevice->TextureTarget, GL_TEXTURE_MIN_LOD, 0.0f); + pOpenGLDevice->glTexParameterf(pOpenGLDevice->TextureTarget, GL_TEXTURE_MAX_LOD, 0.0f); + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_BASE_LEVEL, 0); + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_MAX_LEVEL, 0); + } + const GLenum intfmt = pOpenGLDevice->have_GL_EXT_texture_compression_s3tc ? GL_COMPRESSED_RGBA_S3TC_DXT5_EXT : GL_RGBA; + if ((pOpenGLDevice->have_GL_ARB_texture_rectangle) || (pOpenGLDevice->have_GL_ARB_texture_non_power_of_two) || (_IsPowerOfTwo(width) && _IsPowerOfTwo(height))) { + pOpenGLDevice->glTexImage2D(pOpenGLDevice->TextureTarget, 0, intfmt, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + } + else + { + t->potw = _NextPowerOfTwo(width); + t->poth = _NextPowerOfTwo(height); + pOpenGLDevice->glTexImage2D(pOpenGLDevice->TextureTarget, 0, intfmt, t->potw, t->poth, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + pOpenGLDevice->glTexSubImage2D(pOpenGLDevice->TextureTarget, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + } + + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, CurTexture ? (((gltexture *) CurTexture)->name) : 0); + + if (loadFromFile) + delete[] pixels; +} + +HTEXTURE HGE_Impl::_BuildTexture(int width, int height, DWORD *pixels) +{ + gltexture *retval = new gltexture; + memset(retval, '\0', sizeof (gltexture)); + retval->lost = true; // we'll actually generate a texture and upload when forced. + retval->width = width; + retval->height = height; + retval->pixels = pixels; + return (HTEXTURE)retval; +} + +HTEXTURE CALL HGE_Impl::Texture_Create(int width, int height) +{ + DWORD *pixels = new DWORD[width * height]; + memset(pixels, '\0', sizeof (DWORD) * width * height); + HTEXTURE retval = _BuildTexture(width, height, pixels); + + // the Direct3D renderer doesn't add these to the (textures) list, but we need them for when we "lose" the GL context. + if (retval != 0) + { + CTextureList *texItem=new CTextureList; + texItem->tex=retval; + texItem->width=width; + texItem->height=height; + texItem->next=textures; + textures=texItem; + } + + return retval; +} + +HTEXTURE CALL HGE_Impl::Texture_Load(const char *filename, DWORD size, bool bMipmap) +{ + HTEXTURE retval = 0; + int width = 0; + int height = 0; + + void *data; + DWORD _size; + CTextureList *texItem; + const char *fname = NULL; + if(size) { data=(void *)filename; _size=size; } + else + { + fname = filename; + data=pHGE->Resource_Load(filename, &_size); + if(!data) return 0; + } + + DWORD *pixels = _DecodeImage((BYTE *) data, fname, _size, width, height); + if (pixels != NULL) + retval = _BuildTexture(width, height, pixels); + + if(!size) Resource_Free(data); + + if (retval == 0) + { + STUBBED("texture load fail!"); + _PostError("Can't create texture"); + } + else + { + texItem=new CTextureList; + texItem->tex=retval; + texItem->width=width; + texItem->height=height; + texItem->next=textures; + textures=texItem; + + // force an upload to the GL and lose our copy if it's backed by + // a file. We won't keep it here to conserve system RAM. + if (!size) + { + gltexture *t = (gltexture *) retval; + _ConfigureTexture(t, t->width, t->height, t->pixels); + delete[] t->pixels; + t->pixels = NULL; + t->filename = strcpy(new char[strlen(filename) + 1], filename); + } + } + + return retval; +} + +void CALL HGE_Impl::Texture_Free(HTEXTURE tex) +{ + if (pOpenGLDevice == NULL) + return; // in case we already shut down. + + CTextureList *texItem=textures, *texPrev=0; + + while(texItem) + { + if(texItem->tex==tex) + { + if(texPrev) texPrev->next=texItem->next; + else textures=texItem->next; + delete texItem; + break; + } + texPrev=texItem; + texItem=texItem->next; + } + if(tex) + { + gltexture *pTex = (gltexture *) tex; + delete[] pTex->filename; + delete[] pTex->lock_pixels; + delete[] pTex->pixels; + pOpenGLDevice->glDeleteTextures(1, &pTex->name); + delete pTex; + } +} + +int CALL HGE_Impl::Texture_GetWidth(HTEXTURE tex, bool bOriginal) +{ + CTextureList *texItem=textures; + + if(bOriginal) + { + while(texItem) + { + if(texItem->tex==tex) return texItem->width; + texItem=texItem->next; + } + } + else + { + return ((gltexture*)tex)->width; + } + return 0; +} + + +int CALL HGE_Impl::Texture_GetHeight(HTEXTURE tex, bool bOriginal) +{ + CTextureList *texItem=textures; + + if(bOriginal) + { + while(texItem) + { + if(texItem->tex==tex) return texItem->height; + texItem=texItem->next; + } + } + else + { + return ((gltexture*)tex)->height; + } + return 0; +} + +// HGE extension! +// fast path for pushing YUV video to a texture instead of having to +// lock/convert-to-rgba/unlock...current HGE semantics involve a +// lot of unnecessary overhead on this, not to mention the conversion +// on the CPU is painful on PowerPC chips. +// This lets us use OpenGL extensions to move data to the hardware +// without conversion. +// Don't taunt this function. Side effects are probably rampant. +bool CALL HGE_Impl::HGEEXT_Texture_PushYUV422(HTEXTURE tex, const BYTE *yuv) +{ + if (!pOpenGLDevice->have_GL_APPLE_ycbcr_422) + return false; + + gltexture *pTex=(gltexture*)tex; + assert(!pTex->lock_pixels); + + if (pTex->lost) // just reupload the whole thing. + _ConfigureTexture(pTex, pTex->width, pTex->height, pTex->pixels); + + // Any existing pixels aren't valid anymore. + if (pTex->pixels) + { + delete[] pTex->pixels; + pTex->pixels = NULL; + } + + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, pTex->name); + pOpenGLDevice->glTexSubImage2D(pOpenGLDevice->TextureTarget, 0, 0, 0, + pTex->width, pTex->height, GL_YCBCR_422_APPLE, + GL_UNSIGNED_SHORT_8_8_APPLE, yuv); + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, CurTexture ? (((gltexture *) CurTexture)->name) : 0); + return true; +} + +DWORD * CALL HGE_Impl::Texture_Lock(HTEXTURE tex, bool bReadOnly, int left, int top, int width, int height) +{ + gltexture *pTex=(gltexture*)tex; + + if (pTex->lock_pixels) + { + assert(false && "multiple lock of texture..."); + return 0; + } + + // see if we're backed by a file and not RAM. + const bool loadFromFile = ((pTex->pixels == NULL) && (pTex->filename != NULL)); + if (loadFromFile) + { + DWORD size = 0; + BYTE *data = (BYTE *) pHGE->Resource_Load(pTex->filename, &size); + if (data != NULL) + { + int w, h; + pTex->pixels = _DecodeImage(data, pTex->filename, size, w, h); + if ((w != (int)pTex->width) || (h != (int)pTex->height)) // yikes, file changed? + { + delete[] pTex->pixels; + pTex->pixels = NULL; + } + Resource_Free(data); + } + if (pTex->pixels != NULL) + { + // can't go back to file after we lock, since app might change data. + if (!bReadOnly) + { + delete[] pTex->filename; + pTex->filename = NULL; + } + } + } + + if ((pTex->pixels == NULL) && (!pTex->is_render_target)) // can't lock this texture...?! + return 0; + + // !!! FIXME: is this right? + if((width == 0) && (height == 0)) + { + width = pTex->width; + height = pTex->height; + } + + // !!! FIXME: do something with this? + assert(width > 0); + assert(width <= (int)pTex->width); + assert(height > 0); + assert(height <= (int)pTex->height); + assert(left >= 0); + assert(left <= width); + assert(top >= 0); + assert(top <= height); + + pTex->lock_readonly = bReadOnly; + pTex->lock_x = left; + pTex->lock_y = top; + pTex->lock_width = width; + pTex->lock_height = height; + pTex->lock_pixels = new DWORD[width * height]; + + DWORD *dst = pTex->lock_pixels; + + if (pTex->is_render_target) + { + assert(false && "need to bind fbo before glReadPixels..."); + DWORD *upsideDown = new DWORD[width * height]; + DWORD *src = upsideDown + ((height-1) * width); + pOpenGLDevice->glReadPixels(left, (pTex->height-top)-height, width, height, GL_RGBA, GL_UNSIGNED_BYTE, upsideDown); + for (int i = 0; i < height; i++) + { + memcpy(dst, src, width * sizeof (DWORD)); + dst += width; + src -= width; + } + delete[] upsideDown; + } + else + { + DWORD *src = pTex->pixels + ((top*pTex->width) + left); + for (int i = 0; i < height; i++) + { + memcpy(dst, src, width * sizeof (DWORD)); + dst += width; + src += pTex->width; + } + } + + return pTex->lock_pixels; +} + + +void CALL HGE_Impl::Texture_Unlock(HTEXTURE tex) +{ + gltexture *pTex=(gltexture*)tex; + + if (pTex->lock_pixels == NULL) return; // not locked. + + if (!pTex->lock_readonly) // have to reupload to the hardware. + { + // need to update pTex->pixels ... + const DWORD *src = pTex->lock_pixels; + DWORD *dst = pTex->pixels + ((pTex->lock_y*pTex->width) + pTex->lock_x); + for (int i = 0; i < pTex->lock_height; i++) + { + memcpy(dst, src, pTex->lock_width * sizeof (DWORD)); + dst += pTex->width; + src += pTex->lock_width; + } + + if (pTex->lost) // just reupload the whole thing. + _ConfigureTexture(pTex, pTex->width, pTex->height, pTex->pixels); + else + { + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, pTex->name); + pOpenGLDevice->glTexSubImage2D(pOpenGLDevice->TextureTarget, 0, pTex->lock_x, + (pTex->height-pTex->lock_y)-pTex->lock_height, + pTex->lock_width, pTex->lock_height, GL_RGBA, + GL_UNSIGNED_BYTE, pTex->lock_pixels); + pOpenGLDevice->glBindTexture(pOpenGLDevice->TextureTarget, CurTexture ? (((gltexture *) CurTexture)->name) : 0); + } + } + + // if we were read-only and we're backed by a file, ditch the uncompressed copy in system RAM. + if ((pTex->filename != NULL) && (pTex->lock_readonly)) + { + delete[] pTex->pixels; + pTex->pixels = NULL; + } + + delete[] pTex->lock_pixels; + pTex->lock_pixels = NULL; + pTex->lock_readonly = false; + pTex->lock_x = -1; + pTex->lock_y = -1; + pTex->lock_width = -1; + pTex->lock_height = -1; +} + +//////// Implementation //////// + +#define DEBUG_VERTICES 0 +#if DEBUG_VERTICES +static inline void print_vertex(const hgeVertex *v) +{ + printf(" (%f, %f, %f), 0x%X, (%f, %f)\n", v->x, v->y, v->z, v->col, v->tx, v->ty); +} +#endif + +void HGE_Impl::_render_batch(bool bEndScene) +{ + if(VertArray) + { + if(nPrim) + { + const float h = (float) ((pCurTarget) ? pCurTarget->height : nScreenHeight); + + // texture rectangles range from 0 to size, not 0 to 1. :/ + float texwmult = 1.0f; + float texhmult = 1.0f; + + if (CurTexture) + { + _SetTextureFilter(); + const gltexture *pTex = ((gltexture *)CurTexture); + if (pOpenGLDevice->TextureTarget == GL_TEXTURE_RECTANGLE_ARB) + { + texwmult = pTex->width; + texhmult = pTex->height; + } + else if ((pTex->potw != 0) && (pTex->poth != 0)) + { + texwmult = ( ((float)pTex->width) / ((float)pTex->potw) ); + texhmult = ( ((float)pTex->height) / ((float)pTex->poth) ); + } + } + + for (int i = 0; i < nPrim*CurPrimType; i++) + { + // (0, 0) is the lower left in OpenGL, upper left in D3D. + VertArray[i].y = h - VertArray[i].y; + + // Z axis is inverted in OpenGL from D3D. + VertArray[i].z = -VertArray[i].z; + + // (0, 0) is lower left texcoord in OpenGL, upper left in D3D. + // Also, scale for texture rectangles vs. 2D textures. + VertArray[i].tx *= texwmult; + VertArray[i].ty = (1.0f - VertArray[i].ty) * texhmult; + + // Colors are RGBA in OpenGL, ARGB in Direct3D. + const DWORD color = VertArray[i].col; + BYTE *col = (BYTE *) &VertArray[i].col; + const BYTE a = ((color >> 24) & 0xFF); + const BYTE r = ((color >> 16) & 0xFF); + const BYTE g = ((color >> 8) & 0xFF); + const BYTE b = ((color >> 0) & 0xFF); + col[0] = r; + col[1] = g; + col[2] = b; + col[3] = a; + } + + switch(CurPrimType) + { + case HGEPRIM_QUADS: + pOpenGLDevice->glDrawElements(GL_TRIANGLES, nPrim * 6, GL_UNSIGNED_SHORT, pIB); + #if DEBUG_VERTICES + for (int i = 0; i < nPrim*6; i+=3) + { + printf("QUAD'S TRIANGLE:\n"); + print_vertex(&pVB[pIB[i+0]]); + print_vertex(&pVB[pIB[i+1]]); + print_vertex(&pVB[pIB[i+2]]); + } + printf("DONE.\n"); + #endif + break; + + case HGEPRIM_TRIPLES: + pOpenGLDevice->glDrawArrays(GL_TRIANGLES, 0, nPrim * 3); + break; + + case HGEPRIM_LINES: + pOpenGLDevice->glDrawArrays(GL_LINES, 0, nPrim * 2); + break; + } + + nPrim=0; + } + if(bEndScene) VertArray = 0; + else VertArray = pVB; + } +} + +void HGE_Impl::_SetBlendMode(int blend) +{ + if((blend & BLEND_ALPHABLEND) != (CurBlendMode & BLEND_ALPHABLEND)) + { + if(blend & BLEND_ALPHABLEND) pOpenGLDevice->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + else pOpenGLDevice->glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + + if((blend & BLEND_ZWRITE) != (CurBlendMode & BLEND_ZWRITE)) + { + if(blend & BLEND_ZWRITE) pOpenGLDevice->glDepthMask(GL_TRUE); + else pOpenGLDevice->glDepthMask(GL_FALSE); + } + + if((blend & BLEND_COLORADD) != (CurBlendMode & BLEND_COLORADD)) + { + if(blend & BLEND_COLORADD) pOpenGLDevice->glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); + else pOpenGLDevice->glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + + CurBlendMode = blend; +} + +void HGE_Impl::_SetProjectionMatrix(int width, int height) +{ + pOpenGLDevice->glMatrixMode(GL_PROJECTION); + pOpenGLDevice->glLoadIdentity(); + pOpenGLDevice->glOrtho(0, (float)width, 0, (float)height, 0.0f, 1.0f); + bTransforming = false; + clipX = 0; + clipY = 0; + clipW = width; + clipH = height; +} + +void HGE_Impl::_UnloadOpenGLEntryPoints() +{ + #define GL_PROC(ext,fn,call,ret,params) pOpenGLDevice->fn = NULL; + #include "hge_glfuncs.h" + #undef GL_PROC +} + +bool HGE_Impl::_HaveOpenGLExtension(const char *extlist, const char *ext) +{ + const char *ptr = strstr(extlist, ext); + if (ptr == NULL) + return false; + + const char endchar = ptr[strlen(ext)]; + if ((endchar == '\0') || (endchar == ' ')) + return true; // extension is in the list. + + return false; // just not supported, fail. +} + +bool HGE_Impl::_LoadOpenGLEntryPoints() +{ + System_Log("%s: OpenGL: loading entry points and examining extensions...",GRAPHICS_SRC_FN); + + // these can be reset to false below... + pOpenGLDevice->have_base_opengl = true; + pOpenGLDevice->have_GL_ARB_texture_rectangle = true; + pOpenGLDevice->have_GL_ARB_texture_non_power_of_two = true; + pOpenGLDevice->have_GL_EXT_framebuffer_object = true; + pOpenGLDevice->have_GL_EXT_texture_compression_s3tc = true; + pOpenGLDevice->have_GL_ARB_vertex_buffer_object = true; + pOpenGLDevice->have_GL_APPLE_ycbcr_422 = true; + + #define GL_PROC(ext,fn,call,ret,params) \ + if (pOpenGLDevice->have_##ext) { \ + if ((pOpenGLDevice->fn = (_HGE_PFN_##fn) SDL_GL_GetProcAddress(#fn)) == NULL) { \ + System_Log("Failed to load OpenGL entry point '" #fn "'"); \ + pOpenGLDevice->have_##ext = false; \ + } \ + } else {} + #include "hge_glfuncs.h" + #undef GL_PROC + + if (!pOpenGLDevice->have_base_opengl) + { + _UnloadOpenGLEntryPoints(); + return false; + } + + System_Log("%s: GL_RENDERER: %s",GRAPHICS_SRC_FN, (const char *) pOpenGLDevice->glGetString(GL_RENDERER)); + System_Log("%s: GL_VENDOR: %s",GRAPHICS_SRC_FN, (const char *) pOpenGLDevice->glGetString(GL_VENDOR)); + System_Log("%s: GL_VERSION: %s",GRAPHICS_SRC_FN, (const char *) pOpenGLDevice->glGetString(GL_VERSION)); + + const char *verstr = (const char *) pOpenGLDevice->glGetString(GL_VERSION); + int maj = 0; + int min = 0; + sscanf(verstr, "%d.%d", &maj, &min); + + if ( (maj < 1) || ((maj == 1) && (min < 2)) ) + { + _PostError("OpenGL implementation must be at least version 1.2"); + _UnloadOpenGLEntryPoints(); + return false; + } + + const char *exts = (const char *) pOpenGLDevice->glGetString(GL_EXTENSIONS); + + // NPOT texture support ... + + if (_HaveOpenGLExtension(exts, "GL_ARB_texture_rectangle")) + pOpenGLDevice->have_GL_ARB_texture_rectangle = true; + else if (_HaveOpenGLExtension(exts, "GL_EXT_texture_rectangle")) + pOpenGLDevice->have_GL_ARB_texture_rectangle = true; + else if (_HaveOpenGLExtension(exts, "GL_NV_texture_rectangle")) + pOpenGLDevice->have_GL_ARB_texture_rectangle = true; + else + pOpenGLDevice->have_GL_ARB_texture_rectangle = false; + + if (maj >= 2) + pOpenGLDevice->have_GL_ARB_texture_non_power_of_two = true; + else if (_HaveOpenGLExtension(exts, "GL_ARB_texture_non_power_of_two")) + pOpenGLDevice->have_GL_ARB_texture_non_power_of_two = true; + else + pOpenGLDevice->have_GL_ARB_texture_non_power_of_two = false; + + if (pOpenGLDevice->have_GL_ARB_texture_rectangle) + { + System_Log("%s: OpenGL: Using GL_ARB_texture_rectangle",GRAPHICS_SRC_FN); + pOpenGLDevice->TextureTarget = GL_TEXTURE_RECTANGLE_ARB; + } + else if (pOpenGLDevice->have_GL_ARB_texture_non_power_of_two) + { + System_Log("%s: OpenGL: Using GL_ARB_texture_non_power_of_two",GRAPHICS_SRC_FN); + pOpenGLDevice->TextureTarget = GL_TEXTURE_2D; + } + else + { + // We can fake this with POT textures. Get a real OpenGL! + System_Log("%s: OpenGL: Using power-of-two textures. This costs more memory!",GRAPHICS_SRC_FN); + pOpenGLDevice->TextureTarget = GL_TEXTURE_2D; + } + + // render-to-texture support ... + + // is false if an entry point is missing, but we still need to check for the extension string... + if (pOpenGLDevice->have_GL_EXT_framebuffer_object) + { + // Disable this on Mac OS X Tiger, since some drivers appear to be buggy. + if ((pHGE->MacOSXVersion) && (pHGE->MacOSXVersion < 0x1050)) + pOpenGLDevice->have_GL_EXT_framebuffer_object = false; + else if (_HaveOpenGLExtension(exts, "GL_EXT_framebuffer_object")) + pOpenGLDevice->have_GL_EXT_framebuffer_object = true; + else + pOpenGLDevice->have_GL_EXT_framebuffer_object = false; + } + + if (pOpenGLDevice->have_GL_EXT_framebuffer_object) + System_Log("%s: OpenGL: Using GL_EXT_framebuffer_object",GRAPHICS_SRC_FN); + else + System_Log("%s: OpenGL: WARNING! No render-to-texture support. Things may render badly.",GRAPHICS_SRC_FN); + + + // Texture compression ... + + if (bForceTextureCompression && + _HaveOpenGLExtension(exts, "GL_ARB_texture_compression") && + _HaveOpenGLExtension(exts, "GL_EXT_texture_compression_s3tc")) + pOpenGLDevice->have_GL_EXT_texture_compression_s3tc = true; + else + pOpenGLDevice->have_GL_EXT_texture_compression_s3tc = false; + + if (pOpenGLDevice->have_GL_EXT_texture_compression_s3tc) + System_Log("%s: OpenGL: Using GL_EXT_texture_compression_s3tc",GRAPHICS_SRC_FN); + else if (bForceTextureCompression) + { + bForceTextureCompression = false; // oh well. + System_Log("%s: OpenGL: WARNING: no texture compression support, in a low-memory system.",GRAPHICS_SRC_FN); + System_Log("%s: OpenGL: Performance may be very bad!",GRAPHICS_SRC_FN); + } + + // YUV textures... + + if (_HaveOpenGLExtension(exts, "GL_APPLE_ycbcr_422")) + pOpenGLDevice->have_GL_APPLE_ycbcr_422 = true; + else + pOpenGLDevice->have_GL_APPLE_ycbcr_422 = false; + + if (pOpenGLDevice->have_GL_APPLE_ycbcr_422) + System_Log("%s: OpenGL: Using GL_APPLE_ycbcr_422 to render YUV frames.",GRAPHICS_SRC_FN); + else + System_Log("%s: OpenGL: WARNING: no YUV texture support; videos may render slowly.",GRAPHICS_SRC_FN); + + // VBOs... + + // is false if an entry point is missing, but we still need to check for the extension string... + if (pOpenGLDevice->have_GL_ARB_vertex_buffer_object) + { + if (_HaveOpenGLExtension(exts, "GL_ARB_vertex_buffer_object")) + pOpenGLDevice->have_GL_ARB_vertex_buffer_object = true; + else + pOpenGLDevice->have_GL_ARB_vertex_buffer_object = false; + } + + if (pOpenGLDevice->have_GL_ARB_vertex_buffer_object) + System_Log("%s: OpenGL: Using GL_ARB_vertex_buffer_object",GRAPHICS_SRC_FN); + else + System_Log("%s: OpenGL: WARNING! No VBO support; performance may suffer.",GRAPHICS_SRC_FN); + + return true; +} + +bool HGE_Impl::_GfxInit() +{ + CurTexture = 0; + +// Init OpenGL ... SDL should have created a context at this point. + assert(pOpenGLDevice == NULL); + pOpenGLDevice = new COpenGLDevice; + if (!_LoadOpenGLEntryPoints()) + return false; // already called _PostError(). + + nScreenBPP=SDL_GetVideoSurface()->format->BitsPerPixel; + + _AdjustWindow(); + + System_Log("%s: Mode: %d x %d\n",GRAPHICS_SRC_FN,nScreenWidth,nScreenHeight); +// Create vertex batch buffer + + VertArray=0; + textures=0; + IndexBufferObject=0; + +// Init all stuff that can be lost + + if(!_init_lost()) return false; + + // make sure the framebuffers are cleared and force to screen + pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapBuffers(); + pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SDL_GL_SwapBuffers(); + + return true; +} + +void HGE_Impl::_AdjustWindow() +{ + // no-op. +} + +void HGE_Impl::_Resize(int width, int height) +{ + if(hwndParent) + { + //if(procFocusLostFunc) procFocusLostFunc(); + STUBBED("resize"); + #if 0 + d3dppW.BackBufferWidth=width; + d3dppW.BackBufferHeight=height; + nScreenWidth=width; + nScreenHeight=height; + + _SetProjectionMatrix(nScreenWidth, nScreenHeight); + _GfxRestore(); + #endif + + //if(procFocusGainFunc) procFocusGainFunc(); + } +} + +void HGE_Impl::_GfxDone() +{ + //CRenderTargetList *target=pTargets; + + while(textures) Texture_Free(textures->tex); + while(pTargets) Target_Free((HTARGET) pTargets); + textures=0; + pTargets=0; + + VertArray = 0; + delete[] pVB; + pVB=0; + delete[] pIB; + pIB=0; + + if(pOpenGLDevice) + { + if (pOpenGLDevice->have_GL_ARB_vertex_buffer_object) + { + if (IndexBufferObject != 0) + { + pOpenGLDevice->glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); + pOpenGLDevice->glDeleteBuffersARB(1, &IndexBufferObject); + IndexBufferObject = 0; + } + } + + delete pOpenGLDevice; + pOpenGLDevice=0; + } +} + + +bool HGE_Impl::_GfxRestore() +{ + if(!pOpenGLDevice) return false; + + delete[] pVB; + pVB=0; + + delete[] pIB; + pIB=0; + + _UnloadOpenGLEntryPoints(); + if (!_LoadOpenGLEntryPoints()) + return false; + + if(!_init_lost()) return false; + + if(procGfxRestoreFunc) return procGfxRestoreFunc(); + + return true; +} + + +bool HGE_Impl::_init_lost() +{ + _BindTexture(NULL); // make sure nothing is bound, so everything that we do bind regenerates. + + for (CTextureList *item = textures; item != NULL; item = item->next) + { + gltexture *t = (gltexture *) item->tex; + if (t == NULL) continue; + t->lost = true; + t->name = 0; + } + + CRenderTargetList *target=pTargets; + while(target) + { + gltexture *tex = (gltexture *) target->tex; + _BindTexture(tex); // force texture recreation. + _BindTexture(NULL); + _BuildTarget(target, tex ? tex->name : 0, target->width, target->height, target->depth != 0); + target=target->next; + } + +// Create Vertex buffer + // We just use a client-side array, since you can reasonably count on support + // existing in any GL, and it basically offers the same functionality that + // HGE uses in Direct3D: it locks the vertex buffer, unlocks in time to + // draw something, then relocks again immediately...more or less, that method + // offers the same performance metrics as a client-side array. + // We _will_ stuff the indices in a buffer object, though, if possible, + // since they never change...this matches the D3D behaviour better, since + // they lock, store, and forget about it, but without a buffer object, + // we'd have to pass the array over the bus every glDrawElements() call. + // It's not worth the tapdance for vertex buffer objects though, due to + // HGE's usage patterns. + pVB = new hgeVertex[VERTEX_BUFFER_SIZE]; + +// Create and setup Index buffer + pIB = new GLushort[VERTEX_BUFFER_SIZE*6/4]; + GLushort *pIndices = pIB; + int n = 0; + for(int i=0; i<VERTEX_BUFFER_SIZE/4; i++) { + *pIndices++=n; + *pIndices++=n+1; + *pIndices++=n+2; + *pIndices++=n+2; + *pIndices++=n+3; + *pIndices++=n; + n+=4; + } + + #if !DEBUG_VERTICES // need pIB for DEBUG_VERTICES. + if (pOpenGLDevice->have_GL_ARB_vertex_buffer_object) + { + // stay bound forever. The Index Buffer Object never changes. + pOpenGLDevice->glGenBuffersARB(1, &IndexBufferObject); + pOpenGLDevice->glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, IndexBufferObject); + pOpenGLDevice->glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, sizeof (GLushort) * ((VERTEX_BUFFER_SIZE*6)/4), pIB, GL_STATIC_DRAW); + delete[] pIB; + pIB=0; + } + #endif + + // always use client-side arrays; set it up once at startup. + pOpenGLDevice->glVertexPointer(3, GL_FLOAT, sizeof (hgeVertex), &pVB[0].x); + pOpenGLDevice->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof (hgeVertex), &pVB[0].col); + pOpenGLDevice->glTexCoordPointer(2, GL_FLOAT, sizeof (hgeVertex), &pVB[0].tx); + pOpenGLDevice->glEnableClientState(GL_VERTEX_ARRAY); + pOpenGLDevice->glEnableClientState(GL_COLOR_ARRAY); + pOpenGLDevice->glEnableClientState(GL_TEXTURE_COORD_ARRAY); + +// Set common render states + + pOpenGLDevice->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + pOpenGLDevice->glPixelStorei(GL_PACK_ALIGNMENT, 1); + + //pD3DDevice->SetRenderState( D3DRS_LASTPIXEL, FALSE ); + pOpenGLDevice->glDisable(GL_TEXTURE_2D); + if (pOpenGLDevice->have_GL_ARB_texture_rectangle) + pOpenGLDevice->glDisable(GL_TEXTURE_RECTANGLE_ARB); + pOpenGLDevice->glEnable(pOpenGLDevice->TextureTarget); + pOpenGLDevice->glEnable(GL_SCISSOR_TEST); + pOpenGLDevice->glDisable(GL_CULL_FACE); + pOpenGLDevice->glDisable(GL_LIGHTING); + pOpenGLDevice->glDepthFunc(GL_GEQUAL); + + if (bZBuffer) + pOpenGLDevice->glEnable(GL_DEPTH_TEST); + else + pOpenGLDevice->glDisable(GL_DEPTH_TEST); + + pOpenGLDevice->glEnable(GL_BLEND); + pOpenGLDevice->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + pOpenGLDevice->glEnable(GL_ALPHA_TEST); + pOpenGLDevice->glAlphaFunc(GL_GEQUAL, 1.0f / 255.0f); + + pOpenGLDevice->glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + _SetTextureFilter(); + + // !!! FIXME: this isn't what HGE's Direct3D code does, but the game I'm working with + // !!! FIXME: forces clamping outside of HGE, so I just wedged it in here. + // Apple says texture rectangle on ATI X1000 chips only supports CLAMP_TO_EDGE. + // Texture rectangle only supports CLAMP* wrap modes anyhow. + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + pOpenGLDevice->glTexParameteri(pOpenGLDevice->TextureTarget, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + nPrim=0; + CurPrimType=HGEPRIM_QUADS; + CurBlendMode = BLEND_DEFAULT; + CurTexture = 0; + + pOpenGLDevice->glScissor(0, 0, nScreenWidth, nScreenHeight); + pOpenGLDevice->glViewport(0, 0, nScreenWidth, nScreenHeight); + + // make sure the framebuffer is cleared and force to screen + pOpenGLDevice->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + _SetProjectionMatrix(nScreenWidth, nScreenHeight); + pOpenGLDevice->glMatrixMode(GL_MODELVIEW); + pOpenGLDevice->glLoadIdentity(); + + return true; +} diff --git a/archive/hge/hge_glfuncs.h b/archive/hge/hge_glfuncs.h new file mode 100644 index 0000000..1c0af81 --- /dev/null +++ b/archive/hge/hge_glfuncs.h @@ -0,0 +1,72 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** OpenGL entry points. +*/ + +// don't put #pragma once wrappers in this file, it gets #included +// several times with different #defines for GL_PROC. + +// base GL functionality... +GL_PROC(base_opengl,glEnable,WINGDIAPI,void,(GLenum cap)) +GL_PROC(base_opengl,glDisable,WINGDIAPI,void,(GLenum cap)) +GL_PROC(base_opengl,glGetIntegerv,WINGDIAPI,void,(GLenum pname, GLint *params)) +GL_PROC(base_opengl,glGetString,WINGDIAPI,const GLubyte *,(GLenum name)) +GL_PROC(base_opengl,glGetError,WINGDIAPI,GLenum,(void)) +GL_PROC(base_opengl,glDepthMask,WINGDIAPI,void,(GLboolean flag)) +GL_PROC(base_opengl,glDepthRange,WINGDIAPI,void,(GLclampd zNear, GLclampd zFar)) +GL_PROC(base_opengl,glBlendFunc,WINGDIAPI,void,(GLenum sfactor, GLenum dfactor)) +GL_PROC(base_opengl,glAlphaFunc,WINGDIAPI,void,(GLenum func, GLclampf ref)) +GL_PROC(base_opengl,glDepthFunc,WINGDIAPI,void,(GLenum func)) +GL_PROC(base_opengl,glMatrixMode,WINGDIAPI,void,(GLenum mode)) +GL_PROC(base_opengl,glLoadIdentity,WINGDIAPI,void,(void)) +GL_PROC(base_opengl,glScalef,WINGDIAPI,void,(GLfloat x, GLfloat y, GLfloat z)) +GL_PROC(base_opengl,glViewport,WINGDIAPI,void,(GLint x, GLint y, GLsizei width, GLsizei height)) +GL_PROC(base_opengl,glTranslatef,WINGDIAPI,void,(GLfloat x, GLfloat y, GLfloat z)) +GL_PROC(base_opengl,glRotatef,WINGDIAPI,void,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) +GL_PROC(base_opengl,glOrtho,WINGDIAPI,void,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +GL_PROC(base_opengl,glScissor,WINGDIAPI,void,(GLint x, GLint y, GLsizei width, GLsizei height)) +GL_PROC(base_opengl,glClearColor,WINGDIAPI,void,(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)) +GL_PROC(base_opengl,glClear,WINGDIAPI,void,(GLbitfield mask)) +GL_PROC(base_opengl,glPixelStorei,WINGDIAPI,void,(GLenum pname, GLint param)) +GL_PROC(base_opengl,glBindTexture,WINGDIAPI,void,(GLenum target, GLuint texture)) +GL_PROC(base_opengl,glTexEnvi,WINGDIAPI,void,(GLenum target, GLenum pname, GLint param)) +GL_PROC(base_opengl,glTexParameterf,WINGDIAPI,void,(GLenum target, GLenum pname, GLfloat param)) +GL_PROC(base_opengl,glTexParameteri,WINGDIAPI,void,(GLenum target, GLenum pname, GLint param)) +GL_PROC(base_opengl,glTexImage2D,WINGDIAPI,void,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +GL_PROC(base_opengl,glTexSubImage2D,WINGDIAPI,void,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +GL_PROC(base_opengl,glGenTextures,WINGDIAPI,void,(GLsizei n, GLuint *textures)) +GL_PROC(base_opengl,glDeleteTextures,WINGDIAPI,void,(GLsizei n, const GLuint *textures)) +GL_PROC(base_opengl,glVertexPointer,WINGDIAPI,void,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +GL_PROC(base_opengl,glColorPointer,WINGDIAPI,void,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +GL_PROC(base_opengl,glTexCoordPointer,WINGDIAPI,void,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +GL_PROC(base_opengl,glDrawArrays,WINGDIAPI,void,(GLenum mode, GLint first, GLsizei count)) +GL_PROC(base_opengl,glDrawElements,WINGDIAPI,void,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) +GL_PROC(base_opengl,glEnableClientState,WINGDIAPI,void,(GLenum array)) +GL_PROC(base_opengl,glFinish,WINGDIAPI,void,(void)) +GL_PROC(base_opengl,glReadPixels,WINGDIAPI,void,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) + +// GL_EXT_framebuffer_object ... +GL_PROC(GL_EXT_framebuffer_object,glBindRenderbufferEXT,,void,(GLenum target, GLuint name)) +GL_PROC(GL_EXT_framebuffer_object,glDeleteRenderbuffersEXT,,void,(GLsizei, const GLuint *)) +GL_PROC(GL_EXT_framebuffer_object,glGenRenderbuffersEXT,,void,(GLsizei, GLuint *)) +GL_PROC(GL_EXT_framebuffer_object,glRenderbufferStorageEXT,,void,(GLenum, GLenum, GLsizei, GLsizei)) +GL_PROC(GL_EXT_framebuffer_object,glBindFramebufferEXT,,void,(GLenum, GLuint)) +GL_PROC(GL_EXT_framebuffer_object,glDeleteFramebuffersEXT,,void,(GLsizei, const GLuint *)) +GL_PROC(GL_EXT_framebuffer_object,glGenFramebuffersEXT,,void,(GLsizei, GLuint *)) +GL_PROC(GL_EXT_framebuffer_object,glCheckFramebufferStatusEXT,,GLenum,(GLenum)) +GL_PROC(GL_EXT_framebuffer_object,glFramebufferRenderbufferEXT,,void,(GLenum, GLenum, GLenum, GLuint)) +GL_PROC(GL_EXT_framebuffer_object,glFramebufferTexture2DEXT,,void,(GLenum, GLenum, GLenum, GLuint, GLint)) + +// GL_ARB_vertex_buffer_object ... +GL_PROC(GL_ARB_vertex_buffer_object,glBindBufferARB,,void,(GLenum, GLuint)) +GL_PROC(GL_ARB_vertex_buffer_object,glDeleteBuffersARB,,void,(GLsizei, const GLuint *)) +GL_PROC(GL_ARB_vertex_buffer_object,glGenBuffersARB,,void,(GLsizei, GLuint *)) +GL_PROC(GL_ARB_vertex_buffer_object,glBufferDataARB,,void,(GLenum, GLsizeiptr, const GLvoid *, GLenum)) +GL_PROC(GL_ARB_vertex_buffer_object,glMapBufferARB,,GLvoid*,(GLenum, GLenum)) +GL_PROC(GL_ARB_vertex_buffer_object,glUnmapBufferARB,,GLboolean,(GLenum)) + +// end of hge_glfuncs.h ... + diff --git a/archive/hge/hge_impl.h b/archive/hge/hge_impl.h new file mode 100644 index 0000000..bf42c2f --- /dev/null +++ b/archive/hge/hge_impl.h @@ -0,0 +1,416 @@ +// -*- C++ -*- +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Common core implementation header +*/ + +#ifndef HGE_IMPL_UNIX_H +#define HGE_IMPL_UNIX_H +#include "unix_compat.h" + +#include "hge.h" +#include <stdio.h> +#include <dirent.h> +#include "SDL/SDL.h" + +#define GL_GLEXT_LEGACY 1 +#include "gl.h" + +#ifndef WINGDIAPI +#define WINGDIAPI +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif + +#define GL_PROC(ext,fn,call,ret,params) typedef call ret (APIENTRYP _HGE_PFN_##fn) params; +#include "hge_glfuncs.h" +#undef GL_PROC + +class COpenGLDevice +{ +public: + #define GL_PROC(ext,fn,call,ret,params) _HGE_PFN_##fn fn; + #include "hge_glfuncs.h" + #undef GL_PROC + + GLenum TextureTarget; // texture rectangle vs (npot) 2D. + bool have_base_opengl; + bool have_GL_ARB_texture_rectangle; + bool have_GL_ARB_texture_non_power_of_two; + bool have_GL_EXT_framebuffer_object; + bool have_GL_EXT_texture_compression_s3tc; + bool have_GL_ARB_vertex_buffer_object; + bool have_GL_APPLE_ycbcr_422; +}; + + +#define VERTEX_BUFFER_SIZE 4000 + + +struct gltexture; // used internally. + +struct CRenderTargetList +{ + int width; + int height; + HTEXTURE tex; + GLuint depth; + GLuint frame; + CRenderTargetList* next; +}; + +struct CTextureList +{ + HTEXTURE tex; + int width; + int height; + CTextureList* next; +}; + +struct CResourceList +{ + char filename[_MAX_PATH]; + char password[64]; + CResourceList* next; +}; + +struct CStreamList +{ + HSTREAM hstream; + void* data; + CStreamList* next; +}; + +struct CInputEventList +{ + hgeInputEvent event; + CInputEventList* next; +}; + + +void DInit(); +void DDone(); +bool DFrame(); + + +/* +** HGE Interface implementation +*/ +class HGE_Impl : public HGE +{ +public: + virtual void CALL Release(); + + virtual bool CALL System_Initiate(); + virtual void CALL System_Shutdown(); + virtual bool CALL System_Start(); + virtual void CALL System_SetStateBool (hgeBoolState state, bool value); + virtual void CALL System_SetStateFunc (hgeFuncState state, hgeCallback value); + virtual void CALL System_SetStateHwnd (hgeHwndState state, HWND value); + virtual void CALL System_SetStateInt (hgeIntState state, int value); + virtual void CALL System_SetStateString(hgeStringState state, const char *value); + virtual bool CALL System_GetStateBool (hgeBoolState ); + virtual hgeCallback CALL System_GetStateFunc (hgeFuncState ); + virtual HWND CALL System_GetStateHwnd (hgeHwndState ); + virtual int CALL System_GetStateInt (hgeIntState ); + virtual const char* CALL System_GetStateString(hgeStringState); + virtual const char* CALL System_GetErrorMessage(); + virtual void CALL System_Log(const char *format, ...); + virtual bool CALL System_Launch(const char *url); + virtual void CALL System_Snapshot(const char *filename=0); + + virtual void* CALL Resource_Load(const char *filename, DWORD *size=0); + virtual void CALL Resource_Free(void *res); + virtual bool CALL Resource_AttachPack(const char *filename, const char *password=0); + virtual void CALL Resource_RemovePack(const char *filename); + virtual void CALL Resource_RemoveAllPacks(); + virtual char* CALL Resource_MakePath(const char *filename=0); + virtual char* CALL Resource_EnumFiles(const char *wildcard=0); + virtual char* CALL Resource_EnumFolders(const char *wildcard=0); + + virtual void CALL Ini_SetInt(const char *section, const char *name, int value); + virtual int CALL Ini_GetInt(const char *section, const char *name, int def_val); + virtual void CALL Ini_SetFloat(const char *section, const char *name, float value); + virtual float CALL Ini_GetFloat(const char *section, const char *name, float def_val); + virtual void CALL Ini_SetString(const char *section, const char *name, const char *value); + virtual char* CALL Ini_GetString(const char *section, const char *name, const char *def_val); + + virtual void CALL Random_Seed(int seed=0); + virtual int CALL Random_Int(int min, int max); + virtual float CALL Random_Float(float min, float max); + + virtual float CALL Timer_GetTime(); + virtual float CALL Timer_GetDelta(); + virtual int CALL Timer_GetFPS(); + virtual float CALL Timer_GetFPSf(); + + virtual HEFFECT CALL Effect_Load(const char *filename, DWORD size=0); + virtual void CALL Effect_Free(HEFFECT eff); + virtual HCHANNEL CALL Effect_Play(HEFFECT eff); + virtual HCHANNEL CALL Effect_PlayEx(HEFFECT eff, float volume=1.0, float pan=0.0, float pitch=1.0f, bool loop=false); + + virtual HMUSIC CALL Music_Load(const char *filename, DWORD size=0); + virtual void CALL Music_Free(HMUSIC mus); + virtual HCHANNEL CALL Music_Play(HMUSIC mus, bool loop, int volume = 100, int order = 0, int row = 0); + virtual void CALL Music_SetAmplification(HMUSIC music, int ampl); + virtual int CALL Music_GetAmplification(HMUSIC music); + virtual int CALL Music_GetLength(HMUSIC music); + virtual void CALL Music_SetPos(HMUSIC music, int order, int row); + virtual bool CALL Music_GetPos(HMUSIC music, int *order, int *row); + virtual void CALL Music_SetInstrVolume(HMUSIC music, int instr, int volume); + virtual int CALL Music_GetInstrVolume(HMUSIC music, int instr); + virtual void CALL Music_SetChannelVolume(HMUSIC music, int channel, int volume); + virtual int CALL Music_GetChannelVolume(HMUSIC music, int channel); + + virtual HSTREAM CALL Stream_Load(const char *filename, DWORD size=0); + virtual void CALL Stream_Free(HSTREAM stream); + virtual HCHANNEL CALL Stream_Play(HSTREAM stream, bool loop, int volume = 100); + + virtual void CALL Channel_SetPanning(HCHANNEL chn, float pan); + virtual void CALL Channel_SetVolume(HCHANNEL chn, float volume); + virtual void CALL Channel_SetPitch(HCHANNEL chn, float pitch); + virtual void CALL Channel_Pause(HCHANNEL chn); + virtual void CALL Channel_Resume(HCHANNEL chn); + virtual void CALL Channel_Stop(HCHANNEL chn); + virtual void CALL Channel_PauseAll(); + virtual void CALL Channel_ResumeAll(); + virtual void CALL Channel_StopAll(); + virtual bool CALL Channel_IsPlaying(HCHANNEL chn); + virtual float CALL Channel_GetLength(HCHANNEL chn); + virtual float CALL Channel_GetPos(HCHANNEL chn); + virtual void CALL Channel_SetPos(HCHANNEL chn, float fSeconds); + virtual int CALL Channel_GetPos_BySample(HCHANNEL chn); + virtual void CALL Channel_SetPos_BySample(HCHANNEL chn, int iSample); + virtual void CALL Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan = -101, float pitch = -1); + virtual bool CALL Channel_IsSliding(HCHANNEL channel); + + virtual void CALL Input_GetMousePos(float *x, float *y); + virtual void CALL Input_SetMousePos(float x, float y); + virtual int CALL Input_GetMouseWheel(); + virtual bool CALL Input_IsMouseOver(); + virtual bool CALL Input_KeyDown(int key); + virtual bool CALL Input_KeyUp(int key); + virtual bool CALL Input_GetKeyState(int key); + virtual int CALL Input_GetKeyStateEx(int key); + virtual const char* CALL Input_GetKeyName(int key); + virtual int CALL Input_GetKey(); + virtual int CALL Input_GetChar(); + virtual bool CALL Input_GetEvent(hgeInputEvent *event); + + virtual bool CALL Gfx_BeginScene(HTARGET target=0); + virtual void CALL Gfx_EndScene(); + virtual void CALL Gfx_Clear(DWORD color); + virtual void CALL Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color=0xFFFFFFFF, float z=0.5f); + virtual void CALL Gfx_RenderTriple(const hgeTriple *triple); + virtual void CALL Gfx_RenderQuad(const hgeQuad *quad); + virtual hgeVertex* CALL Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim); + virtual void CALL Gfx_FinishBatch(int nprim); + virtual void CALL Gfx_SetClipping(int x=0, int y=0, int w=0, int h=0); + virtual void CALL Gfx_SetTransform(float x=0, float y=0, float dx=0, float dy=0, float rot=0, float hscale=0, float vscale=0); + + virtual HTARGET CALL Target_Create(int width, int height, bool zbuffer); + virtual void CALL Target_Free(HTARGET target); + virtual HTEXTURE CALL Target_GetTexture(HTARGET target); + + virtual HTEXTURE CALL Texture_Create(int width, int height); + virtual HTEXTURE CALL Texture_Load(const char *filename, DWORD size=0, bool bMipmap=false); + virtual void CALL Texture_Free(HTEXTURE tex); + virtual int CALL Texture_GetWidth(HTEXTURE tex, bool bOriginal=false); + virtual int CALL Texture_GetHeight(HTEXTURE tex, bool bOriginal=false); + virtual DWORD* CALL Texture_Lock(HTEXTURE tex, bool bReadOnly=true, int left=0, int top=0, int width=0, int height=0); + virtual void CALL Texture_Unlock(HTEXTURE tex); + + bool CALL HGEEXT_Texture_PushYUV422(HTEXTURE tex, const BYTE *yuv); + + //////// Implementation //////// + + static HGE_Impl* _Interface_Get(); + void _FocusChange(bool bAct); + void _PostError(const char *error); + + // ini ... + void _LoadIniFile(const char *fname); + const char* _BuildProfilePath(const char *section, const char *name, const char *szIniFile); + bool _WritePrivateProfileString(const char *section, const char *name, const char *buf, const char *szIniFile); + bool _GetPrivateProfileString(const char *section, const char *name, const char *deflt, char *buf, size_t bufsize, const char *szIniFile); + + long MacOSXVersion; + HWND hwnd; + bool bActive; + char szError[256]; + char szAppPath[_MAX_PATH]; + char szIniString[256]; + + + // System States + bool (*procFrameFunc)(); + bool (*procRenderFunc)(); + bool (*procFocusLostFunc)(); + bool (*procFocusGainFunc)(); + bool (*procGfxRestoreFunc)(); + bool (*procExitFunc)(); + const char* szIcon; + char szWinTitle[256]; + int nScreenWidth; + int nScreenHeight; + int nOrigScreenWidth; + int nOrigScreenHeight; + int nScreenBPP; + bool bWindowed; + bool bVsync; + bool bZBuffer; + bool bTextureFilter; + char szIniFile[_MAX_PATH]; + char szLogFile[_MAX_PATH]; + bool bUseSound; + int nSampleRate; + int nFXVolume; + int nMusVolume; + int nStreamVolume; + int nHGEFPS; + bool bHideMouse; + bool bDontSuspend; + HWND hwndParent; + bool bForceTextureCompression; + GLuint IndexBufferObject; + + bool _PrimsOutsideClipping(const hgeVertex *v, const int verts); + bool bTransforming; + int clipX; + int clipY; + int clipW; + int clipH; + +// #ifdef DEMO + bool bDMO; +// #endif + + + // Power + int nPowerStatus; + + void _InitPowerStatus(); + void _UpdatePowerStatus(); + void _DonePowerStatus(); + + + // Graphics + COpenGLDevice* pOpenGLDevice; // GL entry points, dynamically loaded. + hgeVertex* pVB; // vertex buffer is a client-side array in the OpenGL renderer. + GLushort* pIB; // index buffer is a client-side array in the OpenGL renderer. + + CRenderTargetList* pTargets; + CRenderTargetList* pCurTarget; + + //D3DXMATRIX matView; + //D3DXMATRIX matProj; + + CTextureList* textures; + hgeVertex* VertArray; + + int nPrim; + int CurPrimType; + int CurBlendMode; + HTEXTURE CurTexture; + + bool _HaveOpenGLExtension(const char *extlist, const char *ext); + void _UnloadOpenGLEntryPoints(); + bool _LoadOpenGLEntryPoints(); + + bool _GfxInit(); + void _GfxDone(); + bool _GfxRestore(); + void _AdjustWindow(); + void _Resize(int width, int height); + bool _init_lost(); + void _render_batch(bool bEndScene=false); + void _SetTextureFilter(); + void _ConfigureTexture(gltexture *t, int width, int height, DWORD *pixels); + void _BindTexture(gltexture *t); + bool _BuildTarget(CRenderTargetList *pTarget, GLuint texname, int width, int height, bool zbuffer); + HTEXTURE _BuildTexture(int width, int height, DWORD *pixels); + //int _format_id(D3DFORMAT fmt); + void _SetBlendMode(int blend); + void _SetProjectionMatrix(int width, int height); + int _flipSDLSurface(int pitch, int height, void* image_pixels); + + + // Audio + void* hBass; + void* hOpenAL; + bool bSilent; + CStreamList* streams; + bool _SoundInit(); + void _SoundDone(); + void _SetMusVolume(int vol); + void _SetStreamVolume(int vol); + void _SetFXVolume(int vol); + + + // Input + int VKey; + int Char; + int Zpos; + float Xpos; + float Ypos; + SDLMod keymods; + bool bMouseOver; + bool bCaptured; + char keyz[256]; + bool keylast[256]; + CInputEventList* queue; + void _UpdateMouse(); + void _InputInit(); + void _ClearQueue(); + void _BuildEvent(int type, int key, int scan, int flags, int x, int y); + bool _ProcessSDLEvent(const SDL_Event &e); + + // Resources + char szTmpFilename[_MAX_PATH]; + CResourceList* res; + + bool _WildcardMatch(const char *str, const char *wildcard); + bool _PrepareFileEnum(const char *wildcard); + char* _DoEnumIteration(const bool wantdir); + DIR* hSearch; + char szSearchDir[_MAX_PATH]; + char szSearchWildcard[_MAX_PATH]; + char szSearchResult[_MAX_PATH]; + + // Timer + float fTime; + float fDeltaTime; + float fUpdateFPSDelay; + float nFPSf; + DWORD nFixedDelta; + int nFPS; + int Fcnt; + DWORD t0, t0fps, dt; + int cfps; + + +private: + HGE_Impl(); + + #if PLATFORM_MACOSX + void _MacMinimizeWindow(); + void _MacHideOtherWindows(); + void _MacHideWindow(); + #endif +}; + +extern HGE_Impl* pHGE; + +#endif // include-once blocker + +// end of hg_impl_unix.h ... + diff --git a/archive/hge/ini.cpp b/archive/hge/ini.cpp new file mode 100644 index 0000000..6fed586 --- /dev/null +++ b/archive/hge/ini.cpp @@ -0,0 +1,196 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: unix ini file +*/ + +#include "hge_impl.h" + +const char *HGE_Impl::_BuildProfilePath(const char *section, const char *name, const char *szIniFile) +{ + // !!! FIXME: not efficient. + static char path[_MAX_PATH]; + const char *home = getenv("HOME"); + strcpy(path, home); + mkdir(path, S_IRWXU); + + #if PLATFORM_MACOSX + strcat(path, "/Library"); + mkdir(path, S_IRWXU); + strcat(path, "/Application Support"); + mkdir(path, S_IRWXU); + strcat(path, "/"); + strcat(path, szWinTitle); + mkdir(path, S_IRWXU); + #else + strcat(path, "/."); + strcat(path, szWinTitle); + mkdir(path, S_IRWXU); + #endif + + strcat(path, "/inis"); + mkdir(path, S_IRWXU); + + strcat(path, "/"); + strcat(path, szIniFile); + mkdir(path, S_IRWXU); + strcat(path, "/"); + strcat(path, section); + mkdir(path, S_IRWXU); + strcat(path, "/"); + strcat(path, name); + + return path; +} + +bool HGE_Impl::_WritePrivateProfileString(const char *section, const char *name, const char *buf, const char *szIniFile) +{ + const char *path = _BuildProfilePath(section, name, szIniFile); + FILE *io = fopen(path, "wb"); + if (io == NULL) + return false; + const size_t rc = fwrite(buf, strlen(buf), 1, io); + if (fclose(io) == EOF) + return false; + return (rc == 1); +} + +bool HGE_Impl::_GetPrivateProfileString(const char *section, const char *name, const char *deflt, char *buf, size_t bufsize, const char *szIniFile) +{ + bool retval = false; + const char *path = _BuildProfilePath(section, name, szIniFile); + FILE *io = fopen(path, "rb"); + if (io != NULL) + { + const size_t rc = fread(buf, 1, bufsize-1, io); + retval = (ferror(io) == 0); + fclose(io); + if (retval) + buf[rc] = '\0'; + } + + if (!retval) + snprintf(buf, bufsize, "%s", deflt); + + return retval; +} + +// We parse the usual .ini files, and build them into our directory tree when items don't exist. +// !!! FIXME: this code sort of stinks. In fact, the whole directory tree thing could be a mistake... +void HGE_Impl::_LoadIniFile(const char *fname) +{ + char section[128] = { 0 }; + struct stat statbuf; + if (stat(fname, &statbuf) == -1) + return; + FILE *io = fopen(fname, "rb"); + char *buf = new char[statbuf.st_size + 1]; + size_t rc = fread(buf, statbuf.st_size, 1, io); + buf[statbuf.st_size] = '\0'; + fclose(io); + if (rc == 1) + { + char *start = buf; + char *ptr = start; + while (start <= (buf + statbuf.st_size)) + { + while ((*ptr != '\r') && (*ptr != '\n') && (*ptr != '\0')) + ptr++; + *ptr = '\0'; + + while ((*start == ' ') || (*start == '\t') || (*start == '\r') || (*start == '\n')) + start++; + + if ((*start == ';') || (*start == '\0')) // comment or empty line. + ; + else if (*start == '[') // section + { + start++; + char *end = strchr(start, ']'); + if (end != NULL) + { + *end = '\0'; + snprintf(section, sizeof (section), "%s", start); + } + } + else if (section[0] != '\0') + { + char *eq = strchr(start, '='); + if (eq != NULL) + { + *eq = '\0'; + eq++; + char tmpbuf[128]; + if (!_GetPrivateProfileString(section, start, "", tmpbuf, sizeof (tmpbuf), fname)) + _WritePrivateProfileString(section, start, eq, fname); + } + } + ptr++; + start = ptr; + } + } + delete[] buf; +} + +void CALL HGE_Impl::Ini_SetInt(const char *section, const char *name, int value) +{ + char buf[256]; + + if(szIniFile[0]) { + sprintf(buf,"%d",value); + _WritePrivateProfileString(section, name, buf, szIniFile); + } +} + + +int CALL HGE_Impl::Ini_GetInt(const char *section, const char *name, int def_val) +{ + char buf[256]; + + if(szIniFile[0]) { + if(_GetPrivateProfileString(section, name, "", buf, sizeof(buf), szIniFile)) + { return atoi(buf); } + else { return def_val; } + } + return def_val; +} + + +void CALL HGE_Impl::Ini_SetFloat(const char *section, const char *name, float value) +{ + char buf[256]; + + if(szIniFile[0]) { + sprintf(buf,"%f",value); + _WritePrivateProfileString(section, name, buf, szIniFile); + } +} + + +float CALL HGE_Impl::Ini_GetFloat(const char *section, const char *name, float def_val) +{ + char buf[256]; + + if(szIniFile[0]) { + if(_GetPrivateProfileString(section, name, "", buf, sizeof(buf), szIniFile)) + { return (float)atof(buf); } + else { return def_val; } + } + return def_val; +} + + +void CALL HGE_Impl::Ini_SetString(const char *section, const char *name, const char *value) +{ + if(szIniFile[0]) _WritePrivateProfileString(section, name, value, szIniFile); +} + + +char* CALL HGE_Impl::Ini_GetString(const char *section, const char *name, const char *def_val) +{ + if(szIniFile[0]) _GetPrivateProfileString(section, name, def_val, szIniString, sizeof(szIniString), szIniFile); + else strcpy(szIniString, def_val); + return szIniString; +} diff --git a/archive/hge/input.cpp b/archive/hge/input.cpp new file mode 100644 index 0000000..2710c7f --- /dev/null +++ b/archive/hge/input.cpp @@ -0,0 +1,363 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: input +*/ + + +#include "hge_impl.h" + +const char *KeyNames[] = +{ + "?", + "Left Mouse Button", "Right Mouse Button", "?", "Middle Mouse Button", + "?", "?", "?", "Backspace", "Tab", "?", "?", "?", "Enter", "?", "?", + "Shift", "Ctrl", "Alt", "Pause", "Caps Lock", "?", "?", "?", "?", "?", "?", + "Escape", "?", "?", "?", "?", + "Space", "Page Up", "Page Down", "End", "Home", + "Left Arrow", "Up Arrow", "Right Arrow", "Down Arrow", + "?", "?", "?", "?", "Insert", "Delete", "?", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "?", "?", "?", "?", "?", "?", "?", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "Left Win", "Right Win", "Application", "?", "?", + "NumPad 0", "NumPad 1", "NumPad 2", "NumPad 3", "NumPad 4", + "NumPad 5", "NumPad 6", "NumPad 7", "NumPad 8", "NumPad 9", + "Multiply", "Add", "?", "Subtract", "Decimal", "Divide", + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "Num Lock", "Scroll Lock", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "Semicolon", "Equals", "Comma", "Minus", "Period", "Slash", "Grave", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", + "Left bracket", "Backslash", "Right bracket", "Apostrophe", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?" +}; + + +static int SDLKeyToHGEKey(const int sdlkey) +{ + switch (sdlkey) + { + case SDLK_ESCAPE: return HGEK_ESCAPE; + case SDLK_BACKSPACE: return HGEK_BACKSPACE; + case SDLK_TAB: return HGEK_TAB; + case SDLK_RETURN: return HGEK_ENTER; + case SDLK_SPACE: return HGEK_SPACE; + case SDLK_LSHIFT: return HGEK_SHIFT; + case SDLK_RSHIFT: return HGEK_SHIFT; + case SDLK_LCTRL: return HGEK_CTRL; + case SDLK_RCTRL: return HGEK_CTRL; + case SDLK_LALT: return HGEK_ALT; + case SDLK_RALT: return HGEK_ALT; + case SDLK_LMETA: return HGEK_LWIN; + case SDLK_RMETA: return HGEK_RWIN; + //case SDLK_APPS: return HGEK_APPS; + case SDLK_PAUSE: return HGEK_PAUSE; + case SDLK_CAPSLOCK: return HGEK_CAPSLOCK; + case SDLK_NUMLOCK: return HGEK_NUMLOCK; + case SDLK_SCROLLOCK: return HGEK_SCROLLLOCK; + case SDLK_PAGEUP: return HGEK_PGUP; + case SDLK_PAGEDOWN: return HGEK_PGDN; + case SDLK_HOME: return HGEK_HOME; + case SDLK_END: return HGEK_END; + case SDLK_INSERT: return HGEK_INSERT; + case SDLK_DELETE: return HGEK_DELETE; + case SDLK_LEFT: return HGEK_LEFT; + case SDLK_UP: return HGEK_UP; + case SDLK_RIGHT: return HGEK_RIGHT; + case SDLK_DOWN: return HGEK_DOWN; + case SDLK_0: return HGEK_0; + case SDLK_1: return HGEK_1; + case SDLK_2: return HGEK_2; + case SDLK_3: return HGEK_3; + case SDLK_4: return HGEK_4; + case SDLK_5: return HGEK_5; + case SDLK_6: return HGEK_6; + case SDLK_7: return HGEK_7; + case SDLK_8: return HGEK_8; + case SDLK_9: return HGEK_9; + case SDLK_a: return HGEK_A; + case SDLK_b: return HGEK_B; + case SDLK_c: return HGEK_C; + case SDLK_d: return HGEK_D; + case SDLK_e: return HGEK_E; + case SDLK_f: return HGEK_F; + case SDLK_g: return HGEK_G; + case SDLK_h: return HGEK_H; + case SDLK_i: return HGEK_I; + case SDLK_j: return HGEK_J; + case SDLK_k: return HGEK_K; + case SDLK_l: return HGEK_L; + case SDLK_m: return HGEK_M; + case SDLK_n: return HGEK_N; + case SDLK_o: return HGEK_O; + case SDLK_p: return HGEK_P; + case SDLK_q: return HGEK_Q; + case SDLK_r: return HGEK_R; + case SDLK_s: return HGEK_S; + case SDLK_t: return HGEK_T; + case SDLK_u: return HGEK_U; + case SDLK_v: return HGEK_V; + case SDLK_w: return HGEK_W; + case SDLK_x: return HGEK_X; + case SDLK_y: return HGEK_Y; + case SDLK_z: return HGEK_Z; + //case SDLK_GRAVE: return HGEK_GRAVE; + case SDLK_MINUS: return HGEK_MINUS; + case SDLK_EQUALS: return HGEK_EQUALS; + case SDLK_BACKSLASH: return HGEK_BACKSLASH; + case SDLK_LEFTBRACKET: return HGEK_LBRACKET; + case SDLK_RIGHTBRACKET: return HGEK_RBRACKET; + case SDLK_SEMICOLON: return HGEK_SEMICOLON; + case SDLK_QUOTE: return HGEK_APOSTROPHE; + case SDLK_COMMA: return HGEK_COMMA; + case SDLK_PERIOD: return HGEK_PERIOD; + case SDLK_SLASH: return HGEK_SLASH; + case SDLK_KP0: return HGEK_NUMPAD0; + case SDLK_KP1: return HGEK_NUMPAD1; + case SDLK_KP2: return HGEK_NUMPAD2; + case SDLK_KP3: return HGEK_NUMPAD3; + case SDLK_KP4: return HGEK_NUMPAD4; + case SDLK_KP5: return HGEK_NUMPAD5; + case SDLK_KP6: return HGEK_NUMPAD6; + case SDLK_KP7: return HGEK_NUMPAD7; + case SDLK_KP8: return HGEK_NUMPAD8; + case SDLK_KP9: return HGEK_NUMPAD9; + case SDLK_KP_MULTIPLY: return HGEK_MULTIPLY; + case SDLK_KP_DIVIDE: return HGEK_DIVIDE; + case SDLK_KP_PLUS: return HGEK_ADD; + case SDLK_KP_MINUS: return HGEK_SUBTRACT; + case SDLK_KP_PERIOD: return HGEK_DECIMAL; + case SDLK_F1: return HGEK_F1; + case SDLK_F2: return HGEK_F2; + case SDLK_F3: return HGEK_F3; + case SDLK_F4: return HGEK_F4; + case SDLK_F5: return HGEK_F5; + case SDLK_F6: return HGEK_F6; + case SDLK_F7: return HGEK_F7; + case SDLK_F8: return HGEK_F8; + case SDLK_F9: return HGEK_F9; + case SDLK_F10: return HGEK_F10; + case SDLK_F11: return HGEK_F11; + case SDLK_F12: return HGEK_F12; + default: return -1; + } + + return -1; +} + + +bool CALL HGE_Impl::Input_GetEvent(hgeInputEvent *event) +{ + CInputEventList *eptr; + + if(queue) + { + eptr=queue; + memcpy(event, &eptr->event, sizeof(hgeInputEvent)); + queue=eptr->next; + delete eptr; + return true; + } + + return false; +} + +void CALL HGE_Impl::Input_GetMousePos(float *x, float *y) +{ + *x=Xpos; *y=Ypos; +} + + +void CALL HGE_Impl::Input_SetMousePos(float x, float y) +{ + SDL_WarpMouse(x, y); +} + +int CALL HGE_Impl::Input_GetMouseWheel() +{ + return Zpos; +} + +bool CALL HGE_Impl::Input_IsMouseOver() +{ + return bMouseOver; +} + +bool CALL HGE_Impl::Input_GetKeyState(int key) +{ + return (keyz[key] & 4) != 0; +} + +int CALL HGE_Impl::Input_GetKeyStateEx(int key)//New function +{ + if (!Input_GetKeyState(key)&&keylast[key])return HGEKST_RELEASE; + if (!Input_GetKeyState(key))return HGEKST_NONE; + if (Input_GetKeyState(key)&&!keylast[key])return HGEKST_HIT; + return HGEKST_KEEP; +} + +bool CALL HGE_Impl::Input_KeyDown(int key) +{ + return (keyz[key] & 1) != 0; +} + +bool CALL HGE_Impl::Input_KeyUp(int key) +{ + return (keyz[key] & 2) != 0; +} + +const char* CALL HGE_Impl::Input_GetKeyName(int key) +{ + return KeyNames[key]; +} + +int CALL HGE_Impl::Input_GetKey() +{ + return VKey; +} + +int CALL HGE_Impl::Input_GetChar() +{ + return Char; +} + + +//////// Implementation //////// + + +void HGE_Impl::_InputInit() +{ + Xpos = 0; // eh. + Ypos = 0; + memset(&keyz, 0, sizeof(keyz)); +} + +void HGE_Impl::_UpdateMouse() +{ + // no-op. +} + + +void HGE_Impl::_BuildEvent(int type, int key, int scan, int flags, int x, int y) +{ + CInputEventList *last, *eptr=new CInputEventList; + + eptr->event.type=type; + eptr->event.chr=0; + int ptx=x; + int pty=y; + + if(type==INPUT_KEYDOWN) + { + key = SDLKeyToHGEKey(key); + if ( (key < 0) || (key > (int)(sizeof (keyz) / sizeof (keyz[0]))) ) return; + keyz[key] |= 4; + if((flags & HGEINP_REPEAT) == 0) keyz[key] |= 1; + eptr->event.chr = (char) ((key >= 32) && (key <= 127)) ? key : 0; // these map to ASCII in sdl. + } + if(type==INPUT_KEYUP) + { + key = SDLKeyToHGEKey(key); + if ( (key < 0) || (key > (int)(sizeof (keyz) / sizeof (keyz[0]))) ) return; + keyz[key] &= ~4; + keyz[key] |= 2; + eptr->event.chr = (char) ((key >= 32) && (key <= 127)) ? key : 0; // these map to ASCII in sdl. + } + if(type==INPUT_MOUSEWHEEL) + { + eptr->event.key=0; eptr->event.wheel=key; + } + else { eptr->event.key=key; eptr->event.wheel=0; } + + if(type==INPUT_MBUTTONDOWN) + { + keyz[key] |= 1; + keyz[key] |= 4; + //SetCapture(hwnd); + bCaptured=true; + } + if(type==INPUT_MBUTTONUP) + { + keyz[key] |= 2; + keyz[key] &= ~4; + //ReleaseCapture(); + //Input_SetMousePos(Xpos, Ypos); + ptx=(int)Xpos; pty=(int)Ypos; + bCaptured=false; + } + + if(keymods & KMOD_SHIFT) flags|=HGEINP_SHIFT; + if(keymods & KMOD_CTRL) flags|=HGEINP_CTRL; + if(keymods & KMOD_ALT) flags|=HGEINP_ALT; + if(keymods & KMOD_CAPS) flags|=HGEINP_CAPSLOCK; + if(keymods & KMOD_MODE) flags|=HGEINP_SCROLLLOCK; + if(keymods & KMOD_NUM) flags|=HGEINP_NUMLOCK; + eptr->event.flags=flags; + + if(ptx==-1) { eptr->event.x=Xpos;eptr->event.y=Ypos; } + else + { + if(ptx<0) ptx=0; + if(pty<0) pty=0; + if(ptx>=nScreenWidth) ptx=nScreenWidth-1; + if(pty>=nScreenHeight) pty=nScreenHeight-1; + + eptr->event.x=(float)ptx; + eptr->event.y=(float)pty; + } + + eptr->next=0; + + if(!queue) queue=eptr; + else + { + last=queue; + while(last->next) last=last->next; + last->next=eptr; + } + + if(eptr->event.type==INPUT_KEYDOWN || eptr->event.type==INPUT_MBUTTONDOWN) + { + VKey=eptr->event.key;Char=eptr->event.chr; + } + else if(eptr->event.type==INPUT_MOUSEMOVE) + { + Xpos=eptr->event.x;Ypos=eptr->event.y; + } + else if(eptr->event.type==INPUT_MOUSEWHEEL) + { + Zpos+=eptr->event.wheel; + } +} + +void HGE_Impl::_ClearQueue() +{ + CInputEventList *nexteptr, *eptr=queue; + + //memset(&keyz, 0, sizeof(keyz)); + for (int i = 0; i < (int)(sizeof (keyz) / sizeof (keyz[0])); i++) + keyz[i] &= ~3; // only reset some of the bits. + + while(eptr) + { + nexteptr=eptr->next; + delete eptr; + eptr=nexteptr; + } + + queue=0; VKey=0; Char=0; Zpos=0; +} diff --git a/archive/hge/power.cpp b/archive/hge/power.cpp new file mode 100644 index 0000000..eabeeaa --- /dev/null +++ b/archive/hge/power.cpp @@ -0,0 +1,25 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: power status +*/ +//DO NOT USE THIS, USE "acpi". + +#include "hge_impl.h" + +void HGE_Impl::_InitPowerStatus() +{ + nPowerStatus = HGEPWR_UNSUPPORTED; +} + +void HGE_Impl::_UpdatePowerStatus() +{ + nPowerStatus = HGEPWR_UNSUPPORTED; +} + +void HGE_Impl::_DonePowerStatus() +{ + nPowerStatus = HGEPWR_UNSUPPORTED; +} diff --git a/archive/hge/random.cpp b/archive/hge/random.cpp new file mode 100644 index 0000000..ab9956a --- /dev/null +++ b/archive/hge/random.cpp @@ -0,0 +1,31 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: random number generation +*/ + + +#include "hge_impl.h" + +unsigned int g_seed=0; + +void CALL HGE_Impl::Random_Seed(int seed) +{ + if(!seed) g_seed=timeGetTime(); + else g_seed=seed; +} + +int CALL HGE_Impl::Random_Int(int min, int max) +{ + g_seed=214013*g_seed+2531011; + return min+(g_seed ^ g_seed>>15)%(max-min+1); +} + +float CALL HGE_Impl::Random_Float(float min, float max) +{ + g_seed=214013*g_seed+2531011; + //return min+g_seed*(1.0f/4294967295.0f)*(max-min); + return min+(g_seed>>16)*(1.0f/65535.0f)*(max-min); +} diff --git a/archive/hge/resource.cpp b/archive/hge/resource.cpp new file mode 100644 index 0000000..4937ee1 --- /dev/null +++ b/archive/hge/resource.cpp @@ -0,0 +1,394 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: resources management +*/ + +#include "hge_impl.h" + +#include <zlib.h> // the system version is better here. HGE's is out of date. + +#define NOCRYPT +//#define NOUNCRYPT +#include "ZLIB/unzip.h" + + +bool CALL HGE_Impl::Resource_AttachPack(const char *filename, const char *password) +{ + char *szName; + CResourceList *resItem=res; + unzFile zip; + + szName=Resource_MakePath(filename); + + while(resItem) + { + if(!strcmp(szName,resItem->filename)) return false; + resItem=resItem->next; + } + + zip=unzOpen(szName); + if(!zip) { + System_Log("Unable to unzip: %s", szName); + return false; + } + unzClose(zip); + + resItem=new CResourceList; + strcpy(resItem->filename, szName); + if(password) strcpy(resItem->password, password); + else resItem->password[0]=0; + resItem->next=res; + res=resItem; + + return true; +} + +void CALL HGE_Impl::Resource_RemovePack(const char *filename) +{ + char *szName; + CResourceList *resItem=res, *resPrev=0; + + szName=Resource_MakePath(filename); + + while(resItem) + { + if(!strcmp(szName,resItem->filename)) + { + if(resPrev) resPrev->next=resItem->next; + else res=resItem->next; + delete resItem; + break; + } + + resPrev=resItem; + resItem=resItem->next; + } +} + +void CALL HGE_Impl::Resource_RemoveAllPacks() +{ + CResourceList *resItem=res, *resNextItem; + + while(resItem) + { + resNextItem=resItem->next; + delete resItem; + resItem=resNextItem; + } + + res=0; +} + +void* CALL HGE_Impl::Resource_Load(const char *filename, DWORD *size) +{ + const char *res_err="Can't load resource: %s"; + + CResourceList *resItem=res; + char szName[_MAX_PATH]; + char szZipName[_MAX_PATH]; + unzFile zip; + unz_file_info file_info; + int done, i; + void *ptr; + FILE *hF; + + if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') goto _fromfile; // skip absolute paths + + // Load from pack + + strcpy(szName,filename); + for(i=0; szName[i]; i++) { if(szName[i]=='/') szName[i]='\\'; } + + while(resItem) + { + zip=unzOpen(resItem->filename); + done=unzGoToFirstFile(zip); + while(done==UNZ_OK) + { + unzGetCurrentFileInfo(zip, &file_info, szZipName, sizeof(szZipName), NULL, 0, NULL, 0); + for(i=0; szZipName[i]; i++) { if(szZipName[i]=='/') szZipName[i]='\\'; } + if(!strcmp(szName,szZipName)) + { + if(unzOpenCurrentFilePassword(zip, resItem->password[0] ? resItem->password : 0) != UNZ_OK) + { + unzClose(zip); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + ptr = malloc(file_info.uncompressed_size); + if(!ptr) + { + unzCloseCurrentFile(zip); + unzClose(zip); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + if(unzReadCurrentFile(zip, ptr, file_info.uncompressed_size) < 0) + { + unzCloseCurrentFile(zip); + unzClose(zip); + free(ptr); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + unzCloseCurrentFile(zip); + unzClose(zip); + if(size) *size=file_info.uncompressed_size; + return ptr; + } + + done=unzGoToNextFile(zip); + } + + unzClose(zip); + resItem=resItem->next; + } + + // Load from file +_fromfile: + + hF = fopen(Resource_MakePath(filename), "rb"); + if(hF == NULL) + { + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + struct stat statbuf; + if (fstat(fileno(hF), &statbuf) == -1) + { + fclose(hF); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + file_info.uncompressed_size = statbuf.st_size; + ptr = malloc(file_info.uncompressed_size); + if(!ptr) + { + fclose(hF); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + if(fread(ptr, file_info.uncompressed_size, 1, hF) != 1) + { + fclose(hF); + free(ptr); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + fclose(hF); + + if(size) *size=file_info.uncompressed_size; + return ptr; +} + + +void CALL HGE_Impl::Resource_Free(void *res) +{ + if(res) free(res); +} + +// this is from PhysicsFS originally ( http://icculus.org/physfs/ ) +// (also zlib-licensed.) +static int locateOneElement(char *buf) +{ + char *ptr = NULL; + DIR *dirp = NULL; + struct dirent *dent = NULL; + + if (access(buf, F_OK) == 0) + return 1; /* quick rejection: exists in current case. */ + + ptr = strrchr(buf, '/'); /* find entry at end of path. */ + if (ptr == NULL) + { + dirp = opendir("."); + ptr = buf; + } + else + { + *ptr = '\0'; + dirp = opendir(buf); + *ptr = '/'; + ptr++; /* point past dirsep to entry itself. */ + } + + while ((dent = readdir(dirp)) != NULL) + { + if (strcasecmp(dent->d_name, ptr) == 0) + { + strcpy(ptr, dent->d_name); /* found a match. Overwrite with this case. */ + closedir(dirp); + return 1; + } + } + + /* no match at all... */ + closedir(dirp); + return 0; +} + +static int locateCorrectCase(char *buf) +{ + char *ptr = buf; + + while ((ptr = strchr(ptr + 1, '/'))) + { + *ptr = '\0'; /* block this path section off */ + if (!locateOneElement(buf)) + { + *ptr = '/'; /* restore path separator */ + return -2; /* missing element in path. */ + } + *ptr = '/'; /* restore path separator */ + } + + /* check final element... */ + return locateOneElement(buf) ? 0 : -1; +} + +char* CALL HGE_Impl::Resource_MakePath(const char *filename) +{ + int i; + + if(!filename) + strcpy(szTmpFilename, szAppPath); + else if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') + strcpy(szTmpFilename, filename); + else + { + strcpy(szTmpFilename, szAppPath); + if(filename) strcat(szTmpFilename, filename); + } + + for(i=0; szTmpFilename[i]; i++) { if(szTmpFilename[i]=='\\') szTmpFilename[i]='/'; } + + locateCorrectCase(szTmpFilename); + + return szTmpFilename; +} + +// !!! FIXME: kinda messy, and probably doesn't get all the corner cases right. +bool HGE_Impl::_WildcardMatch(const char *str, const char *wildcard) +{ + if ((str == NULL) || (wildcard == NULL)) + return false; + + while ((*str) && (*wildcard)) + { + const char wildch = *wildcard; + const char strch = *str; + if (wildch == '?') + ; // okay. + else if (wildch == '*') + { + do { + wildcard++; + } while (((*wildcard == '*') || (*wildcard == '?')) && (*wildcard != '\0')); + const char newwild = *wildcard; + if (newwild == '\0') return true; + const char *ptr = str; + while (*ptr) // find the greediest match possible... + { + if (*ptr == newwild) + str = ptr; + ptr++; + } + } + else if ( (toupper(strch)) != (toupper(wildch)) ) + { + return false; + } + + str++; + wildcard++; + } + + while (*wildcard == '*') + wildcard++; + + return ((*str == '\0') && (*wildcard == '\0')); +} + +bool HGE_Impl::_PrepareFileEnum(const char *wildcard) +{ + if(hSearch) { closedir(hSearch); hSearch=0; } + char *madepath = Resource_MakePath(wildcard); + const char *fname = strrchr(madepath, '/'); + const char *dir = NULL; + if (fname == NULL) { + dir = "."; + fname = madepath; + } else { + dir = madepath; + char *ptr = (char *) fname; + *ptr = '\0'; // split dir and filename. + fname++; + } + + strcpy(szSearchDir, dir); + strcpy(szSearchWildcard, fname); + + hSearch=opendir(dir); + return (hSearch!=0); +} + +char *HGE_Impl::_DoEnumIteration(const bool wantdir) +{ + if(!hSearch) return 0; + while (true) + { + struct dirent *dent = readdir(hSearch); + if(dent == NULL) { closedir(hSearch); hSearch=0; return 0; } + if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0)) + continue; + if (!_WildcardMatch(dent->d_name, szSearchWildcard)) + continue; + char fullpath[_MAX_PATH]; + snprintf(fullpath, sizeof (fullpath), "%s/%s", szSearchDir, dent->d_name); + struct stat statbuf; + if (stat(fullpath, &statbuf) == -1) // this follows symlinks. + continue; + const bool isdir = ((S_ISDIR(statbuf.st_mode)) != 0); + if (isdir == wantdir) // this treats pipes, devs, etc, as "files" ... + { + strcpy(szSearchResult, dent->d_name); + return szSearchResult; + } + } + return 0; +} + +char* CALL HGE_Impl::Resource_EnumFiles(const char *wildcard) +{ + if(wildcard) + { + if (!_PrepareFileEnum(wildcard)) + return 0; + } + return _DoEnumIteration(false); +} + +char* CALL HGE_Impl::Resource_EnumFolders(const char *wildcard) +{ + if(wildcard) + { + if (!_PrepareFileEnum(wildcard)) + return 0; + } + return _DoEnumIteration(true); +} diff --git a/archive/hge/sound.cpp b/archive/hge/sound.cpp new file mode 100644 index 0000000..9024652 --- /dev/null +++ b/archive/hge/sound.cpp @@ -0,0 +1,531 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: audio routines +*/ + + +// This is just enough to get Hammerfight working without using libBA$$. +// If you want a full HGE audio implementation, you should either use the +// code in sound_libbass.cpp (and maybe pay for a BA$$ licen$e), or improve +// this code. +// Well, this code is now improved by Chris Xiong, adding several new interfaces. +// (Such as seeking in sample...) +// Channel functions are fully supported now. However music and streaming are +// still not supported. Some APIs changed for OpenAL is different from BA$$. + +#include "hge_impl.h" + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" +#include "ogg/ogg.h" +#include "vorbis/vorbisfile.h" +static const char* SOUND_SRC_FN="hge/sound.cpp"; +struct oggcbdata +{ + const BYTE *data; + DWORD size; + DWORD pos; +}; + +static size_t oggcb_read(void *ptr, size_t size, size_t nmemb, void *datasource) +{ + oggcbdata *data = (oggcbdata *) datasource; + const DWORD avail = data->size - data->pos; + size_t want = nmemb * size; + if (want > avail) + want = avail - (avail % size); + if (want > 0) + { + memcpy(ptr, data->data + data->pos, want); + data->pos += want; + } + return want / size; +} + +static int oggcb_seek(void *datasource, ogg_int64_t offset, int whence) +{ + oggcbdata *data = (oggcbdata *) datasource; + ogg_int64_t pos = 0; + switch (whence) + { + case SEEK_SET: pos = offset; break; + case SEEK_CUR: pos = ((ogg_int64_t) data->pos) + offset; break; + case SEEK_END: pos = ((ogg_int64_t) data->size) + offset; break; + default: return -1; + } + + if ( (pos < 0) || (pos > ((ogg_int64_t) data->size)) ) + return -1; + + data->pos = (DWORD) pos; + return 0; +} + +static int oggcb_close(void *datasource) +{ + return 0; +} + +static long oggcb_tell(void *datasource) +{ + oggcbdata *data = (oggcbdata *) datasource; + return (long) data->pos; +} + +static ov_callbacks oggcb = { oggcb_read, oggcb_seek, oggcb_close, oggcb_tell }; + +static void *decompress_vorbis(const BYTE *data, const DWORD size, ALsizei *decompressed_size, ALenum *fmt, ALsizei *freq) +{ +#ifdef __POWERPC__ + const int bigendian = 1; +#else + const int bigendian = 0; +#endif + + oggcbdata cbdata = { data, size, 0 }; + OggVorbis_File vf; + memset(&vf, '\0', sizeof (vf)); + if (ov_open_callbacks(&cbdata, &vf, NULL, 0, oggcb) == 0) + { + int bitstream = 0; + vorbis_info *info = ov_info(&vf, -1); + + *decompressed_size = 0; + *fmt = (info->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + *freq = info->rate; + + if ((info->channels != 1) && (info->channels != 2)) + { + ov_clear(&vf); + return NULL; + } + + char buf[1024 * 16]; + long rc = 0; + size_t allocated = 64 * 1024; + BYTE *retval = (ALubyte *) malloc(allocated); + while ( (rc = ov_read(&vf, buf, sizeof (buf), bigendian, 2, 1, &bitstream)) != 0 ) + { + if (rc > 0) + { + *decompressed_size += rc; + if ((unsigned)*decompressed_size >= allocated) + { + allocated *= 2; + ALubyte *tmp = (ALubyte *) realloc(retval, allocated); + if (tmp == NULL) + { + free(retval); + retval = NULL; + break; + } + retval = tmp; + } + memcpy(retval + (*decompressed_size - rc), buf, rc); + } + } + ov_clear(&vf); + return retval; + } + + return NULL; +} + +#define MAX_SIDS 128 +static int sidcount = 0; +static ALuint sids[MAX_SIDS]; + +static ALuint get_source() +{ + for (int i = 0; i < sidcount; i++) + { + ALint state = AL_PLAYING; + alGetSourceiv(sids[i], AL_SOURCE_STATE, &state); + if ((state != AL_PLAYING) && (state != AL_PAUSED)) + return sids[i]; + } + if (sidcount >= MAX_SIDS) + return 0; + + ALuint sid = 0; + alGenSources(1, &sid); + if (sid == 0) + return 0; + sids[sidcount++] = sid; + return sid; +} + + +HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size) +{ + DWORD _size; + void *data; + + if(hOpenAL) + { + if(bSilent) return 1; + + if(size) { data=(void *)filename; _size=size; } + else + { + data=Resource_Load(filename, &_size); + if(!data) return 0; + } + + const BYTE *magic = (const BYTE *) data; + const bool isOgg = ( (_size > 4) && + (magic[0] == 'O') && (magic[1] == 'g') && + (magic[2] == 'g') && (magic[3] == 'S') ); + if (!isOgg) + { + if(!size) Resource_Free(data); + return 0; + } + void *allocation_decompressed = NULL; + void *decompressed = NULL; + ALsizei decompressed_size = 0; + ALsizei freq = 0; + ALenum fmt = AL_FORMAT_STEREO16; + if (isOgg) + { + /*if (alIsExtensionPresent((const ALchar *) "AL_EXT_vorbis"))//useless + { + fmt = alGetEnumValue((const ALchar *) "AL_FORMAT_VORBIS_EXT"); + decompressed = data; + decompressed_size = _size; + } + else + {*/ + allocation_decompressed = decompress_vorbis((const BYTE *) data, _size, &decompressed_size, &fmt, &freq); + decompressed = allocation_decompressed; + //} + } + + ALuint bid = 0; + alGenBuffers(1, &bid); + alBufferData(bid, fmt, decompressed, decompressed_size, freq); + free(allocation_decompressed); // not delete[] ! + if(!size) Resource_Free(data); + return (HEFFECT) bid; + } + else return 0; +} + +HCHANNEL CALL HGE_Impl::Effect_Play(HEFFECT eff) +{ + return Effect_PlayEx(eff, 1.0f, 0, 1.0f, false); +} + +HCHANNEL CALL HGE_Impl::Effect_PlayEx(HEFFECT eff, float volume, float pan, float pitch, bool loop) +{ + if(hOpenAL) + { + const ALuint sid = get_source(); // find an unused sid, or generate a new one. + if (sid != 0) + { + if (volume < 0) volume = 0; else if (volume > 1.0) volume = 1.0; + if (pan < -1.0) pan = -1.0; else if (pan > 1.0) pan = 1.0; + alSourceStop(sid); + alSourcei(sid, AL_BUFFER, (ALint) eff); + alSourcef(sid, AL_GAIN, volume); + alSourcef(sid, AL_PITCH, pitch); + alSource3f(sid, AL_POSITION, pan, 0.0f, 0.0f); + alSourcei(sid, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); + alSourcePlay(sid); + } + return sid; + } + else return 0; +} + +void CALL HGE_Impl::Effect_Free(HEFFECT eff) +{ + if(hOpenAL) + { + ALuint bid = (ALuint) eff; + alDeleteBuffers(1, &bid); + } +} +//Castrate!! +HMUSIC CALL HGE_Impl::Music_Load(const char *filename, DWORD size){return 0;} + +HCHANNEL CALL HGE_Impl::Music_Play(HMUSIC mus, bool loop, int volume, int order, int row){return 0;} + +void CALL HGE_Impl::Music_Free(HMUSIC mus){} + +void CALL HGE_Impl::Music_SetAmplification(HMUSIC music, int ampl){} + +int CALL HGE_Impl::Music_GetAmplification(HMUSIC music){return -1;} + +int CALL HGE_Impl::Music_GetLength(HMUSIC music){return -1;} + +void CALL HGE_Impl::Music_SetPos(HMUSIC music, int order, int row){} + +bool CALL HGE_Impl::Music_GetPos(HMUSIC music, int *order, int *row){return false;} + +void CALL HGE_Impl::Music_SetInstrVolume(HMUSIC music, int instr, int volume){} + +int CALL HGE_Impl::Music_GetInstrVolume(HMUSIC music, int instr){return -1;} + +void CALL HGE_Impl::Music_SetChannelVolume(HMUSIC music, int channel, int volume){} + +int CALL HGE_Impl::Music_GetChannelVolume(HMUSIC music, int channel){return -1;} + +HSTREAM CALL HGE_Impl::Stream_Load(const char *filename, DWORD size){return 0;} + +void CALL HGE_Impl::Stream_Free(HSTREAM stream){} + +HCHANNEL CALL HGE_Impl::Stream_Play(HSTREAM stream, bool loop, int volume){return 0;} + +void CALL HGE_Impl::Channel_SetPanning(HCHANNEL chn, float pan) +{ + if(pan>1.0)pan=1.0; + if(pan<-1.0)pan=-1.0; + if(hOpenAL) + { + alSource3f((ALuint) chn, AL_POSITION, pan, 0.0f, 0.0f); + } +} + +void CALL HGE_Impl::Channel_SetVolume(HCHANNEL chn, float volume) +{ + if(hOpenAL) + { + if (volume < 0) volume = 0; else if (volume > 1.0f) volume = 1.0f; + alSourcef((ALuint) chn, AL_GAIN, volume); + } +} + +void CALL HGE_Impl::Channel_SetPitch(HCHANNEL chn, float pitch) +{ + if(hOpenAL) + { + alSourcef((ALuint) chn, AL_PITCH, pitch); + } +} + +void CALL HGE_Impl::Channel_Pause(HCHANNEL chn) +{ + if(hOpenAL) + { + alSourcePause((ALuint) chn); + } +} + +void CALL HGE_Impl::Channel_Resume(HCHANNEL chn) +{ + if(hOpenAL) + { + alSourcePlay((ALuint) chn); + } +} + +void CALL HGE_Impl::Channel_Stop(HCHANNEL chn) +{ + if(hOpenAL) + { + alSourceStop((ALuint) chn); + } +} + +void CALL HGE_Impl::Channel_PauseAll() +{ + if(hOpenAL) + { + ALCcontext *ctx = alcGetCurrentContext(); + alcSuspendContext(ctx); + } +} + +void CALL HGE_Impl::Channel_ResumeAll() +{ + if(hOpenAL) + { + ALCcontext *ctx = alcGetCurrentContext(); + alcProcessContext(ctx); + } +} + +void CALL HGE_Impl::Channel_StopAll() +{ + if(hOpenAL) + { + for (int i = 0; i < sidcount; i++) + alSourceStop(sids[i]); + } +} + +bool CALL HGE_Impl::Channel_IsPlaying(HCHANNEL chn) +{ + if(hOpenAL) + { + ALint state = AL_STOPPED; + alGetSourceiv((ALuint) chn, AL_SOURCE_STATE, &state); + return state == AL_PLAYING; + } + else return false; +} +//The following features are ported to OpenAL by Chris +float CALL HGE_Impl::Channel_GetLength(HCHANNEL chn) +//WARNING!!:In OpenAL We pass HEFFECT insteat HCHANNEL in! +//This should be fixed. +{ + //Well, you developers should know this "by heart". + if (hOpenAL) + { + ALint sizeInBytes; + ALint channels; + ALint bits; + ALuint bufferID=chn; + alGetBufferi(bufferID, AL_SIZE, &sizeInBytes); + alGetBufferi(bufferID, AL_CHANNELS, &channels); + alGetBufferi(bufferID, AL_BITS, &bits); + int lengthInSamples = sizeInBytes * 8 / (channels * bits); + ALint frequency; + alGetBufferi(bufferID, AL_FREQUENCY, &frequency); + float durationInSeconds = (float)lengthInSamples / (float)frequency; + return durationInSeconds; + } + return -1; +} + +float CALL HGE_Impl::Channel_GetPos(HCHANNEL chn) +{ + if (hOpenAL) + { + ALfloat res; + alGetSourcef((ALuint)chn,AL_SEC_OFFSET,&res); + return (float)res; + } + else return -1.0f; +} + +void CALL HGE_Impl::Channel_SetPos(HCHANNEL chn, float fSeconds) +{ + if (hOpenAL) + { + alSourcef((ALuint)chn,AL_SEC_OFFSET,(ALfloat)fSeconds); + } +} + +int CALL HGE_Impl::Channel_GetPos_BySample(HCHANNEL chn) +{ + if (hOpenAL) + { + ALint res; + alGetSourcei((ALuint)chn,AL_SAMPLE_OFFSET,&res); + return (int)res; + } + else return -1; +} + +void CALL HGE_Impl::Channel_SetPos_BySample(HCHANNEL chn, int iSample) +{ + if (hOpenAL) + { + alSourcei((ALuint)chn,AL_SAMPLE_OFFSET,(ALint)iSample); + } +} + +void CALL HGE_Impl::Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan, float pitch){} + +bool CALL HGE_Impl::Channel_IsSliding(HCHANNEL channel){return false;} + + +//////// Implementation //////// + + +bool HGE_Impl::_SoundInit() +{ + if(!bUseSound || hOpenAL) return true; + + bSilent=false; + + sidcount = 0; + memset(sids, '\0', sizeof (sids)); + + System_Log("%s: Starting OpenAL init",SOUND_SRC_FN); + + ALCdevice *dev = alcOpenDevice(NULL); + if (!dev) + { + System_Log("%s: alcOpenDevice(NULL) failed, using no sound",SOUND_SRC_FN); + bSilent=true; + return true; + } + + ALint caps[] = { ALC_FREQUENCY, nSampleRate, 0 }; + ALCcontext *ctx = alcCreateContext(dev, caps); + if (!ctx) + { + alcCloseDevice(dev); + System_Log("%s: alcCreateContext(NULL) failed, using no sound",SOUND_SRC_FN); + bSilent=true; + return true; + } + + alcMakeContextCurrent(ctx); + alcProcessContext(ctx); + + System_Log("%s: OpenAL initialized successfully.",SOUND_SRC_FN); + System_Log("%s: AL_VENDOR: %s",SOUND_SRC_FN, (char *) alGetString(AL_VENDOR)); + System_Log("%s: AL_RENDERER: %s",SOUND_SRC_FN, (char *) alGetString(AL_RENDERER)); + System_Log("%s: AL_VERSION: %s",SOUND_SRC_FN,(char *) alGetString(AL_VERSION)); + System_Log("%s: AL_EXTENSIONS: %s",SOUND_SRC_FN,(char *) alGetString(AL_EXTENSIONS)); + + hOpenAL = (void *) 0x1; // something non-NULL (!!! FIXME: this should eventually be a library handle). + + _SetFXVolume(nFXVolume); + //_SetMusVolume(nMusVolume); + //_SetStreamVolume(nStreamVolume); + + return true; +} + +void HGE_Impl::_SoundDone() +{ + CStreamList *stmItem=streams, *stmNext; + + if(hOpenAL) + { + for (int i = 0; i < sidcount; i++) + alSourceStop(sids[i]); + alDeleteSources(sidcount, sids); + sidcount = 0; + memset(sids, '\0', sizeof (sids)); + + ALCcontext *ctx = alcGetCurrentContext(); + ALCdevice *dev = alcGetContextsDevice(ctx); + alcMakeContextCurrent(NULL); + alcSuspendContext(ctx); + alcDestroyContext(ctx); + alcCloseDevice(dev); + + hOpenAL=0; + + while(stmItem) + { + stmNext=stmItem->next; + Resource_Free(stmItem->data); + delete stmItem; + stmItem=stmNext; + } + streams=0; + } +} + +void HGE_Impl::_SetMusVolume(int vol){} + +void HGE_Impl::_SetStreamVolume(int vol){} + +void HGE_Impl::_SetFXVolume(int vol) +{ + if(hOpenAL) + { + alListenerf(AL_GAIN, ((ALfloat) vol) / 100.0f); + } +} diff --git a/archive/hge/system.cpp b/archive/hge/system.cpp new file mode 100644 index 0000000..b32783b --- /dev/null +++ b/archive/hge/system.cpp @@ -0,0 +1,933 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core system functions for Unix. +*/ + + +#include "hge_impl.h" + +#if PLATFORM_MACOSX +#include <Carbon/Carbon.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#endif + +#define LOWORDINT(n) ((int)((signed short)(LOWORD(n)))) +#define HIWORDINT(n) ((int)((signed short)(HIWORD(n)))) +static const char* SYSTEM_SRC_FN="hge/system.cpp"; +int nRef=0; +HGE_Impl* pHGE=0; + +HGE* CALL hgeCreate(int ver) +{ + if(ver==HGE_VERSION) + return (HGE*)HGE_Impl::_Interface_Get(); + else + return 0; +} + + +HGE_Impl* HGE_Impl::_Interface_Get() +{ + if(!pHGE) pHGE=new HGE_Impl(); + + nRef++; + + return pHGE; +} + + +void CALL HGE_Impl::Release() +{ + nRef--; + + if(!nRef) + { + if(pHGE->hwnd) pHGE->System_Shutdown(); + Resource_RemoveAllPacks(); + delete pHGE; + pHGE=0; + } +} + + +bool CALL HGE_Impl::System_Initiate() +{ + + // Log system info + + System_Log("%s: HGE Started...",SYSTEM_SRC_FN); + + System_Log("%s: hge-unix version: %X.%X", SYSTEM_SRC_FN, HGE_VERSION>>8, HGE_VERSION & 0xFF); + + time_t t = time(NULL); + System_Log("%s: Date: %s",SYSTEM_SRC_FN, asctime(localtime(&t))); + + System_Log("%s: Application: %s",SYSTEM_SRC_FN,szWinTitle); + + MacOSXVersion = 0x0000; + +#if PLATFORM_MACOSX + SInt32 ver = 0x0000; + char verbuf[16] = { '\0' }; + if (Gestalt(gestaltSystemVersion, &ver) == noErr) + { + SInt32 macver_minor = ((ver & 0xF0) >> 4); + SInt32 macver_patch = (ver & 0xF); + SInt32 macver_major = ((ver & 0xFF00) >> 8); + macver_major = (((macver_major / 16) * 10) + (macver_major % 16)); + MacOSXVersion = ver; + if (ver >= 0x1030) + { + Gestalt(gestaltSystemVersionMajor, &macver_major); + Gestalt(gestaltSystemVersionMinor, &macver_minor); + Gestalt(gestaltSystemVersionBugFix, &macver_patch); + } + snprintf(verbuf, sizeof (verbuf), "%d.%d.%d", + (int) macver_major, (int) macver_minor, (int) macver_patch); + } + + System_Log("OS: Mac OS X%s", verbuf); + + unsigned long phys = 0; + size_t len = sizeof (phys); + int mib[2] = { CTL_HW, HW_PHYSMEM }; + if ((sysctl(mib, 2, &phys, &len, NULL, 0) != 0) || (len != sizeof (phys))) + phys = 0; // oh well. + phys /= 1024; + System_Log("Memory: %ldK total",phys); + + // !!! FIXME: we shouldn't force this here, really, but the game I'm working + // !!! FIXME: on eats _hundreds_ of megabytes of texture memory. You'll basically + // !!! FIXME: lock the system up, swapping, if you don't force s3tc on low-memory boxes... + bForceTextureCompression = false; //((phys/1024) <= 512); + if (bForceTextureCompression) + { + System_Log("WARNING: we'll have to force texture compression for this system."); + System_Log("WARNING: adding more memory will make the game look better!"); + } + +#else + system("uname -svm > os.out"); + char osv[100];FILE* a=fopen("os.out","r");fgets(osv,50,a);fclose(a); + osv[strlen(osv)-1]='\0'; + System_Log("%s: OS: %s",SYSTEM_SRC_FN,osv); + system("rm os.out"); + a=fopen("/proc/meminfo","r"); + unsigned totalm,freem; + fscanf(a,"MemTotal: %d kB\n",&totalm); + fscanf(a,"MemFree: %d kB\n",&freem); + System_Log("%s: Memory: %ukB total, %ukB free\n",SYSTEM_SRC_FN,totalm,freem); + fclose(a); +#endif + + if (SDL_Init(SDL_INIT_VIDEO) == -1) { + char buffer[1024]; + snprintf(buffer, sizeof (buffer), "%s: SDL_Init() failed: %s\n",SYSTEM_SRC_FN,SDL_GetError()); + _PostError(buffer); + return false; + } + + if (SDL_GL_LoadLibrary(NULL) == -1) { + char buffer[1024]; + snprintf(buffer, sizeof (buffer), "%s: SDL_GL_LoadLibrary() failed: %s\n",SYSTEM_SRC_FN,SDL_GetError()); + _PostError(buffer); + SDL_Quit(); + return false; + } + + const SDL_VideoInfo *vidinfo = SDL_GetVideoInfo(); + nOrigScreenWidth = vidinfo->current_w; + nOrigScreenHeight = vidinfo->current_h; + System_Log("%s: Screen: %dx%d\n",SYSTEM_SRC_FN,nOrigScreenWidth,nOrigScreenHeight); + + // Create window + SDL_WM_SetCaption(szWinTitle, szWinTitle); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, nScreenBPP >= 32 ? 8 : 4); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, nScreenBPP >= 32 ? 8 : 4); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, nScreenBPP >= 32 ? 8 : 4); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, nScreenBPP >= 32 ? 8 : 4); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, bZBuffer ? 16 : 0); + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, bVsync ? 1 : 0); + Uint32 flags = SDL_OPENGL; + if (!bWindowed) + flags |= SDL_FULLSCREEN; + hwnd = SDL_SetVideoMode(nScreenWidth, nScreenHeight, nScreenBPP, flags); + if (!hwnd) + { + char buffer[1024]; + snprintf(buffer, sizeof (buffer), "SDL_SetVideoMode() failed: %s\n", SDL_GetError()); + _PostError(buffer); + SDL_Quit(); + return false; + } + + if (!bWindowed) + { + bMouseOver = true; + if (!pHGE->bActive) + pHGE->_FocusChange(true); + } + + SDL_ShowCursor(bHideMouse ? SDL_DISABLE : SDL_ENABLE); + +#if !PLATFORM_MACOSX + SDL_Surface *icon = SDL_LoadBMP("hgeicon.bmp"); // HACK. + if (icon) + { + SDL_SetColorKey(icon, SDL_SRCCOLORKEY, SDL_MapRGB(icon->format, 255, 0, 255)); + SDL_WM_SetIcon(icon, NULL); + SDL_FreeSurface(icon); + } +#endif + + // Init subsystems + + Random_Seed(); + _InitPowerStatus(); + _InputInit(); + if(!_GfxInit()) { System_Shutdown(); return false; } + if(!_SoundInit()) { System_Shutdown(); return false; } + + System_Log("%s: Init done.\n",SYSTEM_SRC_FN); + + fTime=0.0f; + t0=t0fps=SDL_GetTicks(); + dt=cfps=0; + nFPS=0; + nFPSf=0.0f; + Fcnt=0; + fUpdateFPSDelay=0.0f; + + // Show splash + +//#ifdef DEMO + + bool (*func)(); + bool (*rfunc)(); + HWND hwndTmp; + + if(/*pHGE->bDMO*/true) + { + SDL_Delay(200); + func=(bool(*)())pHGE->System_GetStateFunc(HGE_FRAMEFUNC); + rfunc=(bool(*)())pHGE->System_GetStateFunc(HGE_RENDERFUNC); + hwndTmp=hwndParent; hwndParent=0; + pHGE->System_SetStateFunc(HGE_FRAMEFUNC, DFrame); + pHGE->System_SetStateFunc(HGE_RENDERFUNC, 0); + DInit(); + pHGE->System_Start(); + DDone(); + hwndParent=hwndTmp; + pHGE->System_SetStateFunc(HGE_FRAMEFUNC, func); + pHGE->System_SetStateFunc(HGE_RENDERFUNC, rfunc); + } + +//#endif + + // Done + + return true; +} + +void CALL HGE_Impl::System_Shutdown() +{ + System_Log("\n%s: Closing session..",SYSTEM_SRC_FN); + + if(hSearch) { closedir(hSearch); hSearch=0; } + _ClearQueue(); + _SoundDone(); + _GfxDone(); + _DonePowerStatus(); + + SDL_Quit(); + hwnd=0; + + System_Log("%s: Session ended.",SYSTEM_SRC_FN); +} + + +bool CALL HGE_Impl::System_Start() +{ + if(!hwnd) + { + _PostError("System_Start: System_Initiate wasn't called"); + return false; + } + + if(!procFrameFunc) { + _PostError("System_Start: No frame function defined"); + return false; + } + + bActive=true; + + // MAIN LOOP + for(;;) + { + SDL_Event e; + bool keep_going = true; + while (SDL_PollEvent(&e) && keep_going) + keep_going = _ProcessSDLEvent(e); + + if (!keep_going) + break; + + // Check if mouse is over HGE window for Input_IsMouseOver + + _UpdateMouse(); + + // If HGE window is focused or we have the "don't suspend" state - process the main loop + + if(bActive || bDontSuspend) + { + Uint32 sdlticks; + // Ensure we have at least 1ms time step + // to not confuse user's code with 0 + + do { sdlticks=SDL_GetTicks(); dt = sdlticks - t0; } while(dt < 1); + + // If we reached the time for the next frame + // or we just run in unlimited FPS mode, then + // do the stuff + + if(dt >= nFixedDelta) + { + // fDeltaTime = time step in seconds returned by Timer_GetDelta + + fDeltaTime=dt/1000.0f; + + // Cap too large time steps usually caused by lost focus to avoid jerks + + if(fDeltaTime > 0.2f) + { + fDeltaTime = nFixedDelta ? nFixedDelta/1000.0f : 0.01f; + } + + // Update time counter returned Timer_GetTime + + fTime += fDeltaTime; + + // Store current time for the next frame + // and count FPS + + t0=sdlticks; + if(t0-t0fps <= 1000) cfps++; + else + { + nFPS=cfps; cfps=0; t0fps=t0; + _UpdatePowerStatus(); + } + ++Fcnt;fUpdateFPSDelay+=fDeltaTime; + if(fUpdateFPSDelay>1) + { + nFPSf=Fcnt/fUpdateFPSDelay; + fUpdateFPSDelay=0.0f; + Fcnt=0; + } + + // Do user's stuff + + if(procFrameFunc()) break; + if(procRenderFunc) procRenderFunc(); + + // If if "child mode" - return after processing single frame + + if(hwndParent) break; + + // Clean up input events that were generated by + // WindowProc and weren't handled by user's code + for (int i=1;i<=255;++i) + keylast[i]=Input_GetKeyState(i); + _ClearQueue(); + + // If we use VSYNC - we could afford a little + // sleep to lower CPU usage + + // if(!bWindowed && nHGEFPS==HGEFPS_VSYNC) Sleep(1); + } + + // If we have a fixed frame rate and the time + // for the next frame isn't too close, sleep a bit + + else + { + if(nFixedDelta && dt+3 < nFixedDelta) SDL_Delay(1); + } + } + + // If main loop is suspended - just sleep a bit + // (though not too much to allow instant window + // redraw if requested by OS) + + else SDL_Delay(1); + } + + _ClearQueue(); + + bActive=false; + + return true; +} + +void CALL HGE_Impl::System_SetStateBool(hgeBoolState state, bool value) +{ + switch(state) + { + case HGE_WINDOWED: if(VertArray || hwndParent) break; + if(pOpenGLDevice && bWindowed != value) + { + STUBBED("backbuffer format"); + //if(d3dppW.BackBufferFormat==D3DFMT_UNKNOWN || d3dppFS.BackBufferFormat==D3DFMT_UNKNOWN) break; + + bWindowed=value; + + //if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16; + //else nScreenBPP=32; + + Uint32 flags = SDL_OPENGL; + if (!bWindowed) + flags |= SDL_FULLSCREEN; + hwnd = SDL_SetVideoMode(nScreenWidth, nScreenHeight, nScreenBPP, flags); + _GfxRestore(); + if (!bWindowed) + { + bMouseOver = true; + if (!pHGE->bActive) + pHGE->_FocusChange(true); + } + } + else bWindowed=value; + break; + + case HGE_ZBUFFER: if(!pOpenGLDevice) bZBuffer=value; + break; + + case HGE_TEXTUREFILTER: if (bTextureFilter==value) break; + if(pOpenGLDevice) + _render_batch(); + bTextureFilter=value; + _SetTextureFilter(); + break; + + case HGE_USESOUND: if(bUseSound!=value) + { + bUseSound=value; + if(bUseSound) _SoundInit(); + if(!bUseSound) _SoundDone(); + } + break; + + case HGE_HIDEMOUSE: bHideMouse=value; if (pHGE->hwnd) SDL_ShowCursor(bHideMouse ? SDL_DISABLE : SDL_ENABLE); break; + + case HGE_DONTSUSPEND: bDontSuspend=value; break; + + #ifdef DEMO + case HGE_SHOWSPLASH: bDMO=value; break; + #endif + default:break; + } +} + +void CALL HGE_Impl::System_SetStateFunc(hgeFuncState state, hgeCallback value) +{ + switch(state) + { + case HGE_FRAMEFUNC: procFrameFunc=value; break; + case HGE_RENDERFUNC: procRenderFunc=value; break; + case HGE_FOCUSLOSTFUNC: procFocusLostFunc=value; break; + case HGE_FOCUSGAINFUNC: procFocusGainFunc=value; break; + case HGE_GFXRESTOREFUNC: procGfxRestoreFunc=value; break; + case HGE_EXITFUNC: procExitFunc=value; break; + default:break; + } +} + +void CALL HGE_Impl::System_SetStateHwnd(hgeHwndState state, HWND value) +{ + switch(state) + { + case HGE_HWNDPARENT: + if (value != 0) { + System_Log("WARNING: Trying to set HGE_HWNDPARENT is unsupported!\n"); + System_Log("WARNING: You will not get the behaviour you expect\n"); + } + if(!hwnd) + hwndParent=value; + break; + default:break; + } +} + +void CALL HGE_Impl::System_SetStateInt(hgeIntState state, int value) +{ + switch(state) + { + case HGE_SCREENWIDTH: if(!pOpenGLDevice) nScreenWidth=value; break; + + case HGE_SCREENHEIGHT: if(!pOpenGLDevice) nScreenHeight=value; break; + + case HGE_SCREENBPP: if(!pOpenGLDevice) nScreenBPP=value; break; + + case HGE_SAMPLERATE: if((!hOpenAL) && (!hBass)) nSampleRate=value; + break; + + case HGE_FXVOLUME: nFXVolume=value; + _SetFXVolume(nFXVolume); + break; + + case HGE_MUSVOLUME: nMusVolume=value; + _SetMusVolume(nMusVolume); + break; + + case HGE_STREAMVOLUME: nStreamVolume=value; + _SetStreamVolume(nStreamVolume); + break; + + case HGE_FPS: bVsync = (value==HGEFPS_VSYNC); + if(pOpenGLDevice) SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, bVsync ? 1 : 0); + nHGEFPS=value; + if(nHGEFPS>0) nFixedDelta=int(1000.0f/value); + else nFixedDelta=0; + break; + default:break; + } +} + +void CALL HGE_Impl::System_SetStateString(hgeStringState state, const char *value) +{ + FILE *hf; + + switch(state) + { + case HGE_ICON: szIcon=value; + STUBBED("icon"); + //if(pHGE->hwnd) SetClassLong(pHGE->hwnd, GCL_HICON, (LONG)LoadIcon(pHGE->hInstance, szIcon)); + break; + case HGE_TITLE: strcpy(szWinTitle,value); + if(pHGE->hwnd) SDL_WM_SetCaption(value, value); + break; + case HGE_INIFILE: if(value) { strcpy(szIniFile,Resource_MakePath(value)); _LoadIniFile(szIniFile); } + else szIniFile[0]=0; + break; + case HGE_LOGFILE: if(value) + { + strcpy(szLogFile,Resource_MakePath(value)); + hf=fopen(szLogFile, "w"); + if(!hf) szLogFile[0]=0; + else fclose(hf); + } + else szLogFile[0]=0; + break; + default:break; + } +} + +bool CALL HGE_Impl::System_GetStateBool(hgeBoolState state) +{ + switch(state) + { + case HGE_WINDOWED: return bWindowed; + case HGE_ZBUFFER: return bZBuffer; + case HGE_TEXTUREFILTER: return bTextureFilter; + case HGE_USESOUND: return bUseSound; + case HGE_DONTSUSPEND: return bDontSuspend; + case HGE_HIDEMOUSE: return bHideMouse; + + #ifdef DEMO + case HGE_SHOWSPLASH: return bDMO; + #endif + default:break; + } + + return false; +} + +hgeCallback CALL HGE_Impl::System_GetStateFunc(hgeFuncState state) +{ + switch(state) + { + case HGE_FRAMEFUNC: return procFrameFunc; + case HGE_RENDERFUNC: return procRenderFunc; + case HGE_FOCUSLOSTFUNC: return procFocusLostFunc; + case HGE_FOCUSGAINFUNC: return procFocusGainFunc; + case HGE_EXITFUNC: return procExitFunc; + default:break; + } + + return NULL; +} + +HWND CALL HGE_Impl::System_GetStateHwnd(hgeHwndState state) +{ + switch(state) + { + case HGE_HWND: return hwnd; + case HGE_HWNDPARENT: return hwndParent; + default:break; + } + + return 0; +} + +int CALL HGE_Impl::System_GetStateInt(hgeIntState state) +{ + switch(state) + { + case HGE_ORIGSCREENWIDTH: return nOrigScreenWidth; + case HGE_ORIGSCREENHEIGHT: return nOrigScreenHeight; + case HGE_SCREENWIDTH: return nScreenWidth; + case HGE_SCREENHEIGHT: return nScreenHeight; + case HGE_SCREENBPP: return nScreenBPP; + case HGE_SAMPLERATE: return nSampleRate; + case HGE_FXVOLUME: return nFXVolume; + case HGE_MUSVOLUME: return nMusVolume; + case HGE_STREAMVOLUME: return nStreamVolume; + case HGE_FPS: return nHGEFPS; + case HGE_POWERSTATUS: return nPowerStatus; + default:break; + } + + return 0; +} + +const char* CALL HGE_Impl::System_GetStateString(hgeStringState state) { + switch(state) { + case HGE_ICON: return szIcon; + case HGE_TITLE: return szWinTitle; + case HGE_INIFILE: if(szIniFile[0]) return szIniFile; + else return 0; + case HGE_LOGFILE: if(szLogFile[0]) return szLogFile; + else return 0; + default:break; + } + + return NULL; +} + +const char* CALL HGE_Impl::System_GetErrorMessage() +{ + return szError; +} + +void CALL HGE_Impl::System_Log(const char *szFormat, ...) +{ + FILE *hf = NULL; + va_list ap; + + if(!szLogFile[0]) return; + + hf = fopen(szLogFile, "a"); + if(!hf) return; + + va_start(ap, szFormat); + vfprintf(hf, szFormat, ap); + va_end(ap); + va_start(ap, szFormat); + vfprintf(stderr, szFormat, ap); + va_end(ap); + fprintf(hf, "\n"); + fprintf(stderr, "\n"); + + fclose(hf); +} + +bool CALL HGE_Impl::System_Launch(const char *url) +{ +#if PLATFORM_MACOSX + CFURLRef cfurl = CFURLCreateWithBytes(NULL, (const UInt8 *) url, + strlen(url), kCFStringEncodingUTF8, NULL); + const OSStatus err = LSOpenCFURLRef(cfurl, NULL); + CFRelease(cfurl); + return (err == noErr); +#else + char command[1024];sprintf(command,"xdg-open %s",url); + system(command); + return false; +#endif +} + +void CALL HGE_Impl::System_Snapshot(const char *filename) +{ + char *shotname, tempname[_MAX_PATH]; + int i; + + if(!filename) + { + i=0; + shotname=Resource_EnumFiles("shot???.bmp"); + while(shotname) + { + i++; + shotname=Resource_EnumFiles(); + } + sprintf(tempname, "shot%03d.bmp", i); + filename=Resource_MakePath(tempname); + } + + if(pOpenGLDevice) + { + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + const Uint32 rmask = 0xFF0000; + const Uint32 gmask = 0x00FF00; + const Uint32 bmask = 0x0000FF; + #else + const Uint32 rmask = 0x0000FF; + const Uint32 gmask = 0x00FF00; + const Uint32 bmask = 0xFF0000; + #endif + + pOpenGLDevice->glFinish(); // make sure screenshot is ready. + SDL_Surface *screen = SDL_GetVideoSurface(); + SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 24, rmask, gmask, bmask, 0); + pOpenGLDevice->glReadPixels(0, 0, screen->w, screen->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels); + //flip the image so that it won't be upside down... + _flipSDLSurface(surface->pitch,surface->h,surface->pixels); + SDL_SaveBMP(surface, filename); + SDL_FreeSurface(surface); + } +} + +//////// Implementation //////// + + +HGE_Impl::HGE_Impl() +{ + CurTexture=0; + + //hInstance=GetModuleHandle(0); + hwnd=0; + bActive=false; + szError[0]=0; + + pOpenGLDevice=0; + pTargets=0; + pCurTarget=0; + //pScreenSurf=0; + //pScreenDepth=0; + pVB=0; + pIB=0; + VertArray=0; + textures=0; + + hBass=0; + hOpenAL=0; + bSilent=false; + streams=0; + + hSearch=0; + res=0; + + queue=0; + Char=VKey=Zpos=0; + Xpos=Ypos=0.0f; + bMouseOver=true; + bCaptured=false; + + nHGEFPS=HGEFPS_UNLIMITED; + fTime=0.0f; + fUpdateFPSDelay=0.0f; + fDeltaTime=0.0f; + nFPS=0; + nFPSf=0.0f; + Fcnt=0; + + procFrameFunc=0; + procRenderFunc=0; + procFocusLostFunc=0; + procFocusGainFunc=0; + procGfxRestoreFunc=0; + procExitFunc=0; + szIcon=0; + strcpy(szWinTitle,"HGE"); + nOrigScreenWidth=800; + nOrigScreenHeight=600; + nScreenWidth=800; + nScreenHeight=600; + nScreenBPP=32; + bWindowed=false; + bVsync=false; + bZBuffer=false; + bTextureFilter=true; + szLogFile[0]=0; + szIniFile[0]=0; + bUseSound=true; + nSampleRate=44100; + nFXVolume=100; + nMusVolume=100; + nStreamVolume=100; + nFixedDelta=0; + bHideMouse=true; + bDontSuspend=false; + hwndParent=0; + keymods=KMOD_NONE; + + nPowerStatus=HGEPWR_UNSUPPORTED; + +#ifdef DEMO + bDMO=true; +#endif + + bForceTextureCompression = false; + + STUBBED("get basedir"); +// GetModuleFileName(GetModuleHandle(NULL), szAppPath, sizeof(szAppPath)); + szAppPath[0] = '\0'; + int i; + for(i=strlen(szAppPath)-1; i>0; i--) if(szAppPath[i]=='/') break; + szAppPath[i+1]=0; +} + +void HGE_Impl::_PostError(const char *error) +{ + System_Log(error); + strcpy(szError,error); +} + +void HGE_Impl::_FocusChange(bool bAct) +{ + bActive=bAct; + + if(bActive) + { + if(procFocusGainFunc) procFocusGainFunc(); + } + else + { + if(procFocusLostFunc) procFocusLostFunc(); + } +} + +bool HGE_Impl::_ProcessSDLEvent(const SDL_Event &e) +{ + switch(e.type) + { + case SDL_VIDEOEXPOSE: + if(pHGE->procRenderFunc && pHGE->bWindowed) procRenderFunc(); + break; + + case SDL_QUIT: + if(pHGE->procExitFunc && !pHGE->procExitFunc()) break; + return false; + + case SDL_ACTIVEEVENT: { + const bool bActivating = (e.active.gain != 0); + if (e.active.state & SDL_APPINPUTFOCUS) { + if(pHGE->bActive != bActivating) pHGE->_FocusChange(bActivating); + } + if (e.active.state & SDL_APPMOUSEFOCUS) { + bMouseOver = bActivating; + } + break; + } + + case SDL_KEYDOWN: + keymods = e.key.keysym.mod; + + #if PLATFORM_MACOSX // handle Apple-Q hotkey, etc. + if (keymods & KMOD_META) { + if (e.key.keysym.sym == SDLK_q) { + if(pHGE->procExitFunc && !pHGE->procExitFunc()) break; + return false; + } else if (e.key.keysym.sym == SDLK_m) { + _MacMinimizeWindow(); + break; + } else if (e.key.keysym.sym == SDLK_h) { + if (keymods & KMOD_ALT) + _MacHideOtherWindows(); + else + _MacHideWindow(); + break; + } + } + #endif + + //#if 0 // (my app handles this, actually.) + // hotkey to toggle fullscreen/windowed mode. + if ( (keymods & KMOD_ALT) && ((e.key.keysym.sym == SDLK_RETURN) || (e.key.keysym.sym == SDLK_KP_ENTER)) ) { + System_SetStateBool(HGE_WINDOWED, !bWindowed); + break; + } + //#endif + + pHGE->_BuildEvent(INPUT_KEYDOWN, e.key.keysym.sym, 0, 0 /*(lparam & 0x40000000) ? HGEINP_REPEAT:0*/, -1, -1); + break; + + case SDL_KEYUP: + keymods = e.key.keysym.mod; + pHGE->_BuildEvent(INPUT_KEYUP, e.key.keysym.sym, 0, 0, -1, -1); + break; + + case SDL_MOUSEBUTTONDOWN: + if (e.button.button == SDL_BUTTON_LEFT) + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, 0, e.button.x, e.button.y); + else if (e.button.button == SDL_BUTTON_RIGHT) + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, 0, e.button.x, e.button.y); + else if (e.button.button == SDL_BUTTON_MIDDLE) + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, 0, e.button.x, e.button.y); + else if (e.button.button == SDL_BUTTON_WHEELUP) + pHGE->_BuildEvent(INPUT_MOUSEWHEEL, 1, 0, 0, e.button.x, e.button.y); + else if (e.button.button == SDL_BUTTON_WHEELDOWN) + pHGE->_BuildEvent(INPUT_MOUSEWHEEL, -1, 0, 0, e.button.x, e.button.y); + break; + +#if 0 + case WM_LBUTTONDBLCLK: + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_MBUTTONDBLCLK: + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_RBUTTONDBLCLK: + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; +#endif + + case SDL_MOUSEBUTTONUP: + if (e.button.button == SDL_BUTTON_LEFT) + pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_LBUTTON, 0, 0, e.button.x, e.button.y); + else if (e.button.button == SDL_BUTTON_RIGHT) + pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_RBUTTON, 0, 0, e.button.x, e.button.y); + else if (e.button.button == SDL_BUTTON_MIDDLE) + pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_MBUTTON, 0, 0, e.button.x, e.button.y); + break; + + case SDL_MOUSEMOTION: + pHGE->_BuildEvent(INPUT_MOUSEMOVE, 0, 0, 0, e.motion.x, e.motion.y); + break; + + +#if 0 // !!! FIXME + case WM_SIZE: + if(pHGE->pD3D && wparam==SIZE_RESTORED) pHGE->_Resize(LOWORD(lparam), HIWORD(lparam)); + //return FALSE; + break; +#endif + } + + return true; +} +int HGE_Impl::_flipSDLSurface(int pitch, int height, void* image_pixels) +{ + int index; + void* temp_row; + int height_div_2; + + temp_row=(void *)malloc(pitch); + assert(temp_row); + height_div_2 = (int) (height * .5); + for(index = 0; index < height_div_2; index++) + { + memcpy((Uint8 *)temp_row,(Uint8 *)(image_pixels)+pitch*index,pitch); + memcpy((Uint8 *)(image_pixels)+pitch*index,(Uint8 *)(image_pixels)+pitch*(height-index-1),pitch); + memcpy((Uint8 *)(image_pixels)+pitch*(height-index-1),temp_row,pitch); + } + free(temp_row); + return 0; +} +// end of system_unix.cpp ... diff --git a/archive/hge/timer.cpp b/archive/hge/timer.cpp new file mode 100644 index 0000000..13711c7 --- /dev/null +++ b/archive/hge/timer.cpp @@ -0,0 +1,31 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: timer +*/ + + +#include "hge_impl.h" + + +float CALL HGE_Impl::Timer_GetTime() +{ + return fTime; +} + +float CALL HGE_Impl::Timer_GetDelta() +{ + return fDeltaTime; +} + +int CALL HGE_Impl::Timer_GetFPS() +{ + return nFPS; +} + +float CALL HGE_Impl::Timer_GetFPSf() +{ + return nFPSf; +} diff --git a/archive/hgehelp/hgeanim.cpp b/archive/hgehelp/hgeanim.cpp new file mode 100644 index 0000000..0e370db --- /dev/null +++ b/archive/hgehelp/hgeanim.cpp @@ -0,0 +1,165 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeAnimation helper class implementation +*/ + + +#include "hgeanim.h" + + +hgeAnimation::hgeAnimation(HTEXTURE tex, int nframes, float FPS, float x, float y, float w, float h) + : hgeSprite(tex, x, y, w, h) +{ + orig_width = hge->Texture_GetWidth(tex, true); + + fSinceLastFrame=-1.0f; + fSpeed=1.0f/FPS; + bPlaying=false; + nFrames=nframes; + + Mode=HGEANIM_FWD | HGEANIM_LOOP; + nDelta=1; + SetFrame(0); +} + +hgeAnimation::hgeAnimation(const hgeAnimation & anim) +: hgeSprite(anim) +{ + // Copy hgeAnimation parameters: + this->orig_width = anim.orig_width; + this->bPlaying = anim.bPlaying; + this->fSpeed = anim.fSpeed; + this->fSinceLastFrame = anim.fSinceLastFrame; + this->Mode = anim.Mode; + this->nDelta = anim.nDelta; + this->nFrames = anim.nFrames; + this->nCurFrame = anim.nCurFrame; +} + +void hgeAnimation::SetMode(int mode) +{ + Mode=mode; + + if(mode & HGEANIM_REV) + { + nDelta = -1; + SetFrame(nFrames-1); + } + else + { + nDelta = 1; + SetFrame(0); + } +} + + +void hgeAnimation::Play() +{ + bPlaying=true; + fSinceLastFrame=-1.0f; + if(Mode & HGEANIM_REV) + { + nDelta = -1; + SetFrame(nFrames-1); + } + else + { + nDelta = 1; + SetFrame(0); + } +} + + +void hgeAnimation::Update(float fDeltaTime) +{ + if(!bPlaying) return; + + if(fSinceLastFrame == -1.0f) + fSinceLastFrame=0.0f; + else + fSinceLastFrame += fDeltaTime; + + while(fSinceLastFrame >= fSpeed) + { + fSinceLastFrame -= fSpeed; + + if(nCurFrame + nDelta == nFrames) + { + switch(Mode) + { + case HGEANIM_FWD: + case HGEANIM_REV | HGEANIM_PINGPONG: + bPlaying = false; + break; + + case HGEANIM_FWD | HGEANIM_PINGPONG: + case HGEANIM_FWD | HGEANIM_PINGPONG | HGEANIM_LOOP: + case HGEANIM_REV | HGEANIM_PINGPONG | HGEANIM_LOOP: + nDelta = -nDelta; + break; + } + } + else if(nCurFrame + nDelta < 0) + { + switch(Mode) + { + case HGEANIM_REV: + case HGEANIM_FWD | HGEANIM_PINGPONG: + bPlaying = false; + break; + + case HGEANIM_REV | HGEANIM_PINGPONG: + case HGEANIM_REV | HGEANIM_PINGPONG | HGEANIM_LOOP: + case HGEANIM_FWD | HGEANIM_PINGPONG | HGEANIM_LOOP: + nDelta = -nDelta; + break; + } + } + + if(bPlaying) SetFrame(nCurFrame+nDelta); + } +} + +void hgeAnimation::SetFrame(int n) +{ + float tx1, ty1, tx2, ty2; + bool bX, bY, bHS; + int ncols = int(orig_width) / int(width); + + + n = n % nFrames; + if(n < 0) n = nFrames + n; + nCurFrame = n; + + // calculate texture coords for frame n + ty1 = ty; + tx1 = tx + n*width; + + if(tx1 > orig_width-width) + { + n -= int(orig_width-tx) / int(width); + tx1 = width * (n%ncols); + ty1 += height * (1 + n/ncols); + } + + tx2 = tx1 + width; + ty2 = ty1 + height; + + tx1 /= tex_width; + ty1 /= tex_height; + tx2 /= tex_width; + ty2 /= tex_height; + + quad.v[0].tx=tx1; quad.v[0].ty=ty1; + quad.v[1].tx=tx2; quad.v[1].ty=ty1; + quad.v[2].tx=tx2; quad.v[2].ty=ty2; + quad.v[3].tx=tx1; quad.v[3].ty=ty2; + + bX=bXFlip; bY=bYFlip; bHS=bHSFlip; + bXFlip=false; bYFlip=false; + SetFlip(bX,bY,bHS); +} + diff --git a/archive/hgehelp/hgecolor.cpp b/archive/hgehelp/hgecolor.cpp new file mode 100644 index 0000000..561a9cc --- /dev/null +++ b/archive/hgehelp/hgecolor.cpp @@ -0,0 +1,89 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeColor*** helper classes implementation +*/ + + +#include "hgecolor.h" +#include <math.h> + +#ifndef min +#define min(x,y) ((x) < (y) ? (x) : (y)) +#endif + +#ifndef max +#define max(x,y) ((x) > (y) ? (x) : (y)) +#endif + +void hgeColorHSV::SetHWColor(DWORD col) +{ + float r, g, b; + float minv, maxv, delta; + float del_R, del_G, del_B; + + a = (col>>24) / 255.0f; + r = ((col>>16) & 0xFF) / 255.0f; + g = ((col>>8) & 0xFF) / 255.0f; + b = (col & 0xFF) / 255.0f; + + minv = min(min(r, g), b); + maxv = max(max(r, g), b); + delta = maxv - minv; + + v = maxv; + + if (delta == 0) + { + h = 0; + s = 0; + } + else + { + s = delta / maxv; + del_R = (((maxv - r) / 6) + (delta / 2)) / delta; + del_G = (((maxv - g) / 6) + (delta / 2)) / delta; + del_B = (((maxv - b) / 6) + (delta / 2)) / delta; + + if (r == maxv) {h = del_B - del_G;} + else if (g == maxv) {h = (1.0f / 3.0f) + del_R - del_B;} + else if (b == maxv) {h = (2.0f / 3.0f) + del_G - del_R;} + + if (h < 0) h += 1; + if (h > 1) h -= 1; + } +} + +DWORD hgeColorHSV::GetHWColor() const +{ + float r, g, b; + float xh, i, p1, p2, p3; + + if (s == 0) + { + r = v; + g = v; + b = v; + } + else + { + xh = h * 6; + if(xh == 6) xh=0; + i = floorf(xh); + p1 = v * (1 - s); + p2 = v * (1 - s * (xh - i)); + p3 = v * (1 - s * (1 - (xh - i))); + + if (i == 0) {r = v; g = p3; b = p1;} + else if (i == 1) {r = p2; g = v; b = p1;} + else if (i == 2) {r = p1; g = v; b = p3;} + else if (i == 3) {r = p1; g = p2; b = v; } + else if (i == 4) {r = p3; g = p1; b = v; } + else {r = v; g = p1; b = p2;} + } + + return (DWORD(a*255.0f)<<24) + (DWORD(r*255.0f)<<16) + (DWORD(g*255.0f)<<8) + DWORD(b*255.0f); +} + diff --git a/archive/hgehelp/hgedistort.cpp b/archive/hgehelp/hgedistort.cpp new file mode 100644 index 0000000..c7dc821 --- /dev/null +++ b/archive/hgehelp/hgedistort.cpp @@ -0,0 +1,242 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeDistortionMesh helper class implementation +*/ + +#include "hgedistort.h" + + +HGE *hgeDistortionMesh::hge=0; + + +hgeDistortionMesh::hgeDistortionMesh(int cols, int rows) +{ + int i; + + hge=hgeCreate(HGE_VERSION); + + nRows=rows; + nCols=cols; + cellw=cellh=0; + quad.tex=0; + quad.blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_ZWRITE; + disp_array=new hgeVertex[rows*cols]; + + for(i=0;i<rows*cols;i++) + { + disp_array[i].x=0.0f; + disp_array[i].y=0.0f; + disp_array[i].tx=0.0f; + disp_array[i].ty=0.0f; + + disp_array[i].z=0.5f; + disp_array[i].col=0xFFFFFFFF; + } +} + +hgeDistortionMesh::hgeDistortionMesh(const hgeDistortionMesh &dm) +{ + hge=hgeCreate(HGE_VERSION); + + nRows=dm.nRows; + nCols=dm.nCols; + cellw=dm.cellw; + cellh=dm.cellh; + tx=dm.tx; + ty=dm.ty; + width=dm.width; + height=dm.height; + quad=dm.quad; + + disp_array=new hgeVertex[nRows*nCols]; + memcpy(disp_array, dm.disp_array, sizeof(hgeVertex)*nRows*nCols); +} + +hgeDistortionMesh::~hgeDistortionMesh() +{ + delete[] disp_array; + hge->Release(); +} + +hgeDistortionMesh& hgeDistortionMesh::operator= (const hgeDistortionMesh &dm) +{ + if(this!=&dm) + { + nRows=dm.nRows; + nCols=dm.nCols; + cellw=dm.cellw; + cellh=dm.cellh; + tx=dm.tx; + ty=dm.ty; + width=dm.width; + height=dm.height; + quad=dm.quad; + + delete[] disp_array; + disp_array=new hgeVertex[nRows*nCols]; + memcpy(disp_array, dm.disp_array, sizeof(hgeVertex)*nRows*nCols); + } + + return *this; + +} + +void hgeDistortionMesh::SetTexture(HTEXTURE tex) +{ + quad.tex=tex; +} + +void hgeDistortionMesh::SetTextureRect(float x, float y, float w, float h) +{ + int i,j; + float tw,th; + + tx=x; ty=y; width=w; height=h; + + if (quad.tex) + { + tw=(float)hge->Texture_GetWidth(quad.tex); + th=(float)hge->Texture_GetHeight(quad.tex); + } + else + { + tw = w; + th = h; + } + + cellw=w/(nCols-1); + cellh=h/(nRows-1); + + for(j=0; j<nRows; j++) + for(i=0; i<nCols; i++) + { + disp_array[j*nCols+i].tx=(x+i*cellw)/tw; + disp_array[j*nCols+i].ty=(y+j*cellh)/th; + + disp_array[j*nCols+i].x=i*cellw; + disp_array[j*nCols+i].y=j*cellh; + } +} + +void hgeDistortionMesh::SetBlendMode(int blend) +{ + quad.blend=blend; +} + +void hgeDistortionMesh::Clear(DWORD col, float z) +{ + int i,j; + + for(j=0; j<nRows; j++) + for(i=0; i<nCols; i++) + { + disp_array[j*nCols+i].x=i*cellw; + disp_array[j*nCols+i].y=j*cellh; + disp_array[j*nCols+i].col=col; + disp_array[j*nCols+i].z=z; + } +} + +void hgeDistortionMesh::Render(float x, float y) +{ + int i,j,idx; + + for(j=0; j<nRows-1; j++) + for(i=0; i<nCols-1; i++) + { + idx=j*nCols+i; + + quad.v[0].tx=disp_array[idx].tx; + quad.v[0].ty=disp_array[idx].ty; + quad.v[0].x=x+disp_array[idx].x; + quad.v[0].y=y+disp_array[idx].y; + quad.v[0].z=disp_array[idx].z; + quad.v[0].col=disp_array[idx].col; + + quad.v[1].tx=disp_array[idx+1].tx; + quad.v[1].ty=disp_array[idx+1].ty; + quad.v[1].x=x+disp_array[idx+1].x; + quad.v[1].y=y+disp_array[idx+1].y; + quad.v[1].z=disp_array[idx+1].z; + quad.v[1].col=disp_array[idx+1].col; + + quad.v[2].tx=disp_array[idx+nCols+1].tx; + quad.v[2].ty=disp_array[idx+nCols+1].ty; + quad.v[2].x=x+disp_array[idx+nCols+1].x; + quad.v[2].y=y+disp_array[idx+nCols+1].y; + quad.v[2].z=disp_array[idx+nCols+1].z; + quad.v[2].col=disp_array[idx+nCols+1].col; + + quad.v[3].tx=disp_array[idx+nCols].tx; + quad.v[3].ty=disp_array[idx+nCols].ty; + quad.v[3].x=x+disp_array[idx+nCols].x; + quad.v[3].y=y+disp_array[idx+nCols].y; + quad.v[3].z=disp_array[idx+nCols].z; + quad.v[3].col=disp_array[idx+nCols].col; + + hge->Gfx_RenderQuad(&quad); + } +} + +void hgeDistortionMesh::SetZ(int col, int row, float z) +{ + if(row<nRows && col<nCols) disp_array[row*nCols+col].z=z; +} + +void hgeDistortionMesh::SetColor(int col, int row, DWORD color) +{ + if(row<nRows && col<nCols) disp_array[row*nCols+col].col=color; +} + +void hgeDistortionMesh::SetDisplacement(int col, int row, float dx, float dy, int ref) +{ + if(row<nRows && col<nCols) + { + switch(ref) + { + case HGEDISP_NODE: dx+=col*cellw; dy+=row*cellh; break; + case HGEDISP_CENTER: dx+=cellw*(nCols-1)/2;dy+=cellh*(nRows-1)/2; break; + case HGEDISP_TOPLEFT: break; + } + + disp_array[row*nCols+col].x=dx; + disp_array[row*nCols+col].y=dy; + } +} + +float hgeDistortionMesh::GetZ(int col, int row) const +{ + if(row<nRows && col<nCols) return disp_array[row*nCols+col].z; + else return 0.0f; +} + +DWORD hgeDistortionMesh::GetColor(int col, int row) const +{ + if(row<nRows && col<nCols) return disp_array[row*nCols+col].col; + else return 0; +} + +void hgeDistortionMesh::GetDisplacement(int col, int row, float *dx, float *dy, int ref) const +{ + if(row<nRows && col<nCols) + { + switch(ref) + { + case HGEDISP_NODE: *dx=disp_array[row*nCols+col].x-col*cellw; + *dy=disp_array[row*nCols+col].y-row*cellh; + break; + + case HGEDISP_CENTER: *dx=disp_array[row*nCols+col].x-cellw*(nCols-1)/2; + *dy=disp_array[row*nCols+col].x-cellh*(nRows-1)/2; + break; + + case HGEDISP_TOPLEFT: *dx=disp_array[row*nCols+col].x; + *dy=disp_array[row*nCols+col].y; + break; + } + } +} + diff --git a/archive/hgehelp/hgefont.cpp b/archive/hgehelp/hgefont.cpp new file mode 100644 index 0000000..eb06393 --- /dev/null +++ b/archive/hgehelp/hgefont.cpp @@ -0,0 +1,337 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeFont helper class implementation +*/ + + +#include "hgefont.h" +#include <stdlib.h> +#include <stdio.h> + +const char FNTHEADERTAG[] = "[HGEFONT]"; +const char FNTBITMAPTAG[] = "Bitmap"; +const char FNTCHARTAG[] = "Char"; + + +HGE *hgeFont::hge=0; +char hgeFont::buffer[1024]; + + +hgeFont::hgeFont(const char *szFont, bool bMipmap) +{ + void *data; + DWORD size; + char *desc, *pdesc; + char linebuf[256]; + char buf[MAX_PATH], *pbuf; + char chr; + int i, x, y, w, h, a, c; + + // Setup variables + + hge=hgeCreate(HGE_VERSION); + + fHeight=0.0f; + fScale=1.0f; + fProportion=1.0f; + fRot=0.0f; + fTracking=0.0f; + fSpacing=1.0f; + hTexture=0; + + fZ=0.5f; + nBlend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + dwCol=0xFFFFFFFF; + + ZeroMemory( &letters, sizeof(letters) ); + ZeroMemory( &pre, sizeof(pre) ); + ZeroMemory( &post, sizeof(post) ); + + // Load font description + + data=hge->Resource_Load(szFont, &size); + if(!data) return; + + desc = new char[size+1]; + memcpy(desc,data,size); + desc[size]=0; + hge->Resource_Free(data); + + pdesc=_get_line(desc,linebuf); + if(strcmp(linebuf, FNTHEADERTAG)) + { + hge->System_Log("Font %s has incorrect format.", szFont); + delete[] desc; + return; + } + + // Parse font description + + while((pdesc = _get_line(pdesc,linebuf))) + { + if(!strncmp(linebuf, FNTBITMAPTAG, sizeof(FNTBITMAPTAG)-1 )) + { + strcpy(buf,szFont); + pbuf=strrchr(buf,'\\'); + if(!pbuf) pbuf=strrchr(buf,'/'); + if(!pbuf) pbuf=buf; + else pbuf++; + if(!sscanf(linebuf, "Bitmap = %s", pbuf)) continue; + + hTexture=hge->Texture_Load(buf, 0, bMipmap); + if(!hTexture) + { + delete[] desc; + return; + } + } + + else if(!strncmp(linebuf, FNTCHARTAG, sizeof(FNTCHARTAG)-1 )) + { + pbuf=strchr(linebuf,'='); + if(!pbuf) continue; + pbuf++; + while(*pbuf==' ') pbuf++; + if(*pbuf=='\"') + { + pbuf++; + i=(unsigned char)*pbuf++; + pbuf++; // skip " + } + else + { + i=0; + while((*pbuf>='0' && *pbuf<='9') || (*pbuf>='A' && *pbuf<='F') || (*pbuf>='a' && *pbuf<='f')) + { + chr=*pbuf; + if(chr >= 'a') chr-='a'-':'; + if(chr >= 'A') chr-='A'-':'; + chr-='0'; + if(chr>0xF) chr=0xF; + i=(i << 4) | chr; + pbuf++; + } + if(i<0 || i>255) continue; + } + sscanf(pbuf, " , %d , %d , %d , %d , %d , %d", &x, &y, &w, &h, &a, &c); + + letters[i] = new hgeSprite(hTexture, (float)x, (float)y, (float)w, (float)h); + pre[i]=(float)a; + post[i]=(float)c; + if(h>fHeight) fHeight=(float)h; + } + } + + delete[] desc; +} + + +hgeFont::~hgeFont() +{ + for(int i=0; i<256; i++) + if(letters[i]) delete letters[i]; + if(hTexture) hge->Texture_Free(hTexture); + hge->Release(); +} + +void hgeFont::Render(float x, float y, int align, const char *string) +{ + int i; + float fx=x; + + align &= HGETEXT_HORZMASK; + if(align==HGETEXT_RIGHT) fx-=GetStringWidth(string, false); + if(align==HGETEXT_CENTER) fx-=int(GetStringWidth(string, false)/2.0f); + + while(*string) + { + if(*string=='\n') + { + y += int(fHeight*fScale*fSpacing); + fx = x; + if(align == HGETEXT_RIGHT) fx -= GetStringWidth(string+1, false); + if(align == HGETEXT_CENTER) fx -= int(GetStringWidth(string+1, false)/2.0f); + } + else + { + i=(unsigned char)*string; + if(!letters[i]) i='?'; + if(letters[i]) + { + fx += pre[i]*fScale*fProportion; + letters[i]->RenderEx(fx, y, fRot, fScale*fProportion, fScale); + fx += (letters[i]->GetWidth()+post[i]+fTracking)*fScale*fProportion; + } + } + string++; + } +} + +void hgeFont::printf(float x, float y, int align, const char *format, ...) +{ + va_list vl; + + va_start(vl, format); + vsnprintf(buffer, sizeof(buffer)-1, format, vl); + va_end(vl); + + buffer[sizeof(buffer)-1] = '\0'; + + Render(x,y,align,buffer); +} + +void hgeFont::printfb(float x, float y, float w, float h, int align, const char *format, ...) +{ + char chr, *pbuf, *prevword, *linestart; + int i,lines=0; + float tx, ty, hh, ww; + va_list vl; + + va_start(vl, format); + vsnprintf(buffer, sizeof(buffer)-1, format, vl); + va_end(vl); + + buffer[sizeof(buffer)-1] = '\0'; + + linestart=buffer; + pbuf=buffer; + prevword=0; + + for(;;) + { + i=0; + while(pbuf[i] && pbuf[i]!=' ' && pbuf[i]!='\n') i++; + + chr=pbuf[i]; + pbuf[i]=0; + ww=GetStringWidth(linestart); + pbuf[i]=chr; + + if(ww > w) + { + if(pbuf==linestart) + { + pbuf[i]='\n'; + linestart=&pbuf[i+1]; + } + else + { + *prevword='\n'; + linestart=prevword+1; + } + + lines++; + } + + if(pbuf[i]=='\n') + { + prevword=&pbuf[i]; + linestart=&pbuf[i+1]; + pbuf=&pbuf[i+1]; + lines++; + continue; + } + + if(!pbuf[i]) {lines++;break;} + + prevword=&pbuf[i]; + pbuf=&pbuf[i+1]; + } + + tx=x; + ty=y; + hh=fHeight*fSpacing*fScale*lines; + + switch(align & HGETEXT_HORZMASK) + { + case HGETEXT_LEFT: break; + case HGETEXT_RIGHT: tx+=w; break; + case HGETEXT_CENTER: tx+=int(w/2); break; + } + + switch(align & HGETEXT_VERTMASK) + { + case HGETEXT_TOP: break; + case HGETEXT_BOTTOM: ty+=h-hh; break; + case HGETEXT_MIDDLE: ty+=int((h-hh)/2); break; + } + + Render(tx,ty,align,buffer); +} + +float hgeFont::GetStringWidth(const char *string, bool bMultiline) const +{ + int i; + float linew, w = 0; + + while(*string) + { + linew = 0; + + while(*string && *string != '\n') + { + i=(unsigned char)*string; + if(!letters[i]) i='?'; + if(letters[i]) + linew += letters[i]->GetWidth() + pre[i] + post[i] + fTracking; + + string++; + } + + if(!bMultiline) return linew*fScale*fProportion; + + if(linew > w) w = linew; + + while (*string == '\n' || *string == '\r') string++; + } + + return w*fScale*fProportion; +} + +void hgeFont::SetColor(DWORD col) +{ + dwCol = col; + + for(int i=0; i<256; i++) + if(letters[i]) + letters[i]->SetColor(col); +} + +void hgeFont::SetZ(float z) +{ + fZ = z; + + for(int i=0; i<256; i++) + if(letters[i]) + letters[i]->SetZ(z); +} + +void hgeFont::SetBlendMode(int blend) +{ + nBlend = blend; + + for(int i=0; i<256; i++) + if(letters[i]) + letters[i]->SetBlendMode(blend); +} + +char *hgeFont::_get_line(char *file, char *line) +{ + int i=0; + + if(!file[i]) return 0; + + while(file[i] && file[i]!='\n' && file[i]!='\r') + { + line[i]=file[i]; + i++; + } + line[i]=0; + + while(file[i] && (file[i]=='\n' || file[i]=='\r')) i++; + + return file + i; +} diff --git a/archive/hgehelp/hgegui.cpp b/archive/hgehelp/hgegui.cpp new file mode 100644 index 0000000..2faf24c --- /dev/null +++ b/archive/hgehelp/hgegui.cpp @@ -0,0 +1,397 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeGUI helper class implementation +*/ + + +#include "hgegui.h" + + +HGE *hgeGUI::hge=0; +HGE *hgeGUIObject::hge=0; + + +hgeGUI::hgeGUI() +{ + hge=hgeCreate(HGE_VERSION); + + ctrls=0; + ctrlLock=0; + ctrlFocus=0; + ctrlOver=0; + navmode=HGEGUI_NONAVKEYS; + bLPressed=bLReleased=false; + bRPressed=bRReleased=false; + nWheel=0; + mx=my=0.0f; + nEnterLeave=0; + sprCursor=0; +} + +hgeGUI::~hgeGUI() +{ + hgeGUIObject *ctrl=ctrls, *nextctrl; + + while(ctrl) + { + nextctrl=ctrl->next; + delete ctrl; + ctrl=nextctrl; + } + + hge->Release(); +} + +void hgeGUI::AddCtrl(hgeGUIObject *ctrl) +{ + hgeGUIObject *last=ctrls; + + ctrl->gui=this; + + if(!ctrls) + { + ctrls=ctrl; + ctrl->prev=0; + ctrl->next=0; + } + else + { + while(last->next) last=last->next; + last->next=ctrl; + ctrl->prev=last; + ctrl->next=0; + } +} + +void hgeGUI::DelCtrl(int id) +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + if(ctrl->id == id) + { + if(ctrl->prev) ctrl->prev->next = ctrl->next; + else ctrls = ctrl->next; + if(ctrl->next) ctrl->next->prev = ctrl->prev; + delete ctrl; + return; + } + ctrl=ctrl->next; + } +} + +hgeGUIObject* hgeGUI::GetCtrl(int id) const +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + if(ctrl->id == id) return ctrl; + ctrl=ctrl->next; + } + + return NULL; +} + +void hgeGUI::MoveCtrl(int id, float x, float y) +{ + hgeGUIObject *ctrl=GetCtrl(id); + ctrl->rect.x2=x + (ctrl->rect.x2 - ctrl->rect.x1); + ctrl->rect.y2=y + (ctrl->rect.y2 - ctrl->rect.y1); + ctrl->rect.x1=x; + ctrl->rect.y1=y; +} + +void hgeGUI::ShowCtrl(int id, bool bVisible) +{ + GetCtrl(id)->bVisible=bVisible; +} + +void hgeGUI::EnableCtrl(int id, bool bEnabled) +{ + GetCtrl(id)->bEnabled=bEnabled; +} + +void hgeGUI::SetNavMode(int mode) +{ + navmode=mode; +} + +void hgeGUI::SetCursor(hgeSprite *spr) +{ + sprCursor=spr; +} + + +void hgeGUI::SetColor(DWORD color) +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->SetColor(color); + ctrl=ctrl->next; + } +} + + +void hgeGUI::Reset() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->Reset(); + ctrl=ctrl->next; + } + + ctrlLock=0; + ctrlOver=0; + ctrlFocus=0; +} + + +void hgeGUI::Move(float dx, float dy) +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->rect.x1 += dx; + ctrl->rect.y1 += dy; + ctrl->rect.x2 += dx; + ctrl->rect.y2 += dy; + + ctrl=ctrl->next; + } +} + + +void hgeGUI::SetFocus(int id) +{ + hgeGUIObject *ctrlNewFocus=GetCtrl(id); + + if(ctrlNewFocus==ctrlFocus) return; + if(!ctrlNewFocus) + { + if(ctrlFocus) ctrlFocus->Focus(false); + ctrlFocus=0; + } + else if(!ctrlNewFocus->bStatic && ctrlNewFocus->bVisible && ctrlNewFocus->bEnabled) + { + if(ctrlFocus) ctrlFocus->Focus(false); + if(ctrlNewFocus) ctrlNewFocus->Focus(true); + ctrlFocus=ctrlNewFocus; + } +} + +int hgeGUI::GetFocus() const +{ + if(ctrlFocus) return ctrlFocus->id; + else return 0; +} + +void hgeGUI::Enter() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->Enter(); + ctrl=ctrl->next; + } + + nEnterLeave=2; +} + +void hgeGUI::Leave() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + ctrl->Leave(); + ctrl=ctrl->next; + } + + ctrlFocus=0; + ctrlOver=0; + ctrlLock=0; + nEnterLeave=1; +} + +void hgeGUI::Render() +{ + hgeGUIObject *ctrl=ctrls; + + while(ctrl) + { + if(ctrl->bVisible) ctrl->Render(); + ctrl=ctrl->next; + } + + if(hge->Input_IsMouseOver() && sprCursor) sprCursor->Render(mx,my); +} + +int hgeGUI::Update(float dt) +{ + bool bDone; + int key; + hgeGUIObject *ctrl; + +// Update the mouse variables + + hge->Input_GetMousePos(&mx, &my); + bLPressed = hge->Input_KeyDown(HGEK_LBUTTON); + bLReleased = hge->Input_KeyUp(HGEK_LBUTTON); + bRPressed = hge->Input_KeyDown(HGEK_RBUTTON); + bRReleased = hge->Input_KeyUp(HGEK_RBUTTON); + nWheel=hge->Input_GetMouseWheel(); + +// Update all controls + + ctrl=ctrls; + while(ctrl) + { + ctrl->Update(dt); + ctrl=ctrl->next; + } + +// Handle Enter/Leave + + if(nEnterLeave) + { + ctrl=ctrls; bDone=true; + while(ctrl) + { + if(!ctrl->IsDone()) { bDone=false; break; } + ctrl=ctrl->next; + } + if(!bDone) return 0; + else + { + if(nEnterLeave==1) return -1; + else nEnterLeave=0; + } + } + +// Handle keys + + key=hge->Input_GetKey(); + if(((navmode & HGEGUI_LEFTRIGHT) && key==HGEK_LEFT) || + ((navmode & HGEGUI_UPDOWN) && key==HGEK_UP)) + { + ctrl=ctrlFocus; + if(!ctrl) + { + ctrl=ctrls; + if(!ctrl) return 0; + } + do { + ctrl=ctrl->prev; + if(!ctrl && ((navmode & HGEGUI_CYCLED) || !ctrlFocus)) + { + ctrl=ctrls; + while(ctrl->next) ctrl=ctrl->next; + } + if(!ctrl || ctrl==ctrlFocus) break; + } while(ctrl->bStatic==true || ctrl->bVisible==false || ctrl->bEnabled==false); + + if(ctrl && ctrl!=ctrlFocus) + { + if(ctrlFocus) ctrlFocus->Focus(false); + if(ctrl) ctrl->Focus(true); + ctrlFocus=ctrl; + } + } + else if(((navmode & HGEGUI_LEFTRIGHT) && key==HGEK_RIGHT) || + ((navmode & HGEGUI_UPDOWN) && key==HGEK_DOWN)) + { + ctrl=ctrlFocus; + if(!ctrl) + { + ctrl=ctrls; + if(!ctrl) return 0; + while(ctrl->next) ctrl=ctrl->next; + } + do { + ctrl=ctrl->next; + if(!ctrl && ((navmode & HGEGUI_CYCLED) || !ctrlFocus)) ctrl=ctrls; + if(!ctrl || ctrl==ctrlFocus) break; + } while(ctrl->bStatic==true || ctrl->bVisible==false || ctrl->bEnabled==false); + + if(ctrl && ctrl!=ctrlFocus) + { + if(ctrlFocus) ctrlFocus->Focus(false); + if(ctrl) ctrl->Focus(true); + ctrlFocus=ctrl; + } + } + else if(ctrlFocus && key && key!=HGEK_LBUTTON && key!=HGEK_RBUTTON) + { + if(ctrlFocus->KeyClick(key, hge->Input_GetChar())) return ctrlFocus->id; + } + +// Handle mouse + + bool bLDown = hge->Input_GetKeyState(HGEK_LBUTTON); + bool bRDown = hge->Input_GetKeyState(HGEK_RBUTTON); + + if(ctrlLock) + { + ctrl=ctrlLock; + if(!bLDown && !bRDown) ctrlLock=0; + if(ProcessCtrl(ctrl)) return ctrl->id; + } + else + { + // Find last (topmost) control + + ctrl=ctrls; + if(ctrl) + while(ctrl->next) ctrl=ctrl->next; + + while(ctrl) + { + if(ctrl->rect.TestPoint(mx,my) && ctrl->bEnabled) + { + if(ctrlOver != ctrl) + { + if(ctrlOver) ctrlOver->MouseOver(false); + ctrl->MouseOver(true); + ctrlOver=ctrl; + } + + if(ProcessCtrl(ctrl)) return ctrl->id; + else return 0; + } + ctrl=ctrl->prev; + } + + if(ctrlOver) {ctrlOver->MouseOver(false); ctrlOver=0;} + + } + + return 0; +} + +bool hgeGUI::ProcessCtrl(hgeGUIObject *ctrl) +{ + bool bResult=false; + + if(bLPressed) { ctrlLock=ctrl;SetFocus(ctrl->id);bResult=bResult || ctrl->MouseLButton(true); } + if(bRPressed) { ctrlLock=ctrl;SetFocus(ctrl->id);bResult=bResult || ctrl->MouseRButton(true); } + if(bLReleased) { bResult=bResult || ctrl->MouseLButton(false); } + if(bRReleased) { bResult=bResult || ctrl->MouseRButton(false); } + if(nWheel) { bResult=bResult || ctrl->MouseWheel(nWheel); } + bResult=bResult || ctrl->MouseMove(mx-ctrl->rect.x1,my-ctrl->rect.y1); + + return bResult; +} + + + diff --git a/archive/hgehelp/hgeguictrls.cpp b/archive/hgehelp/hgeguictrls.cpp new file mode 100644 index 0000000..4319491 --- /dev/null +++ b/archive/hgehelp/hgeguictrls.cpp @@ -0,0 +1,362 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeGUI default controls implementation +*/ + + +#include "hgeguictrls.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +/* +** hgeGUIText +*/ + +hgeGUIText::hgeGUIText(int _id, float x, float y, float w, float h, hgeFont *fnt) +{ + id=_id; + bStatic=true; + bVisible=true; + bEnabled=true; + rect.Set(x, y, x+w, y+h); + + font=fnt; + tx=x; + ty=y+(h-fnt->GetHeight())/2.0f; + + text[0]=0; +} + +void hgeGUIText::SetMode(int _align) +{ + align=_align; + if(align==HGETEXT_RIGHT) tx=rect.x2; + else if(align==HGETEXT_CENTER) tx=(rect.x1+rect.x2)/2.0f; + else tx=rect.x1; +} + +void hgeGUIText::SetText(const char *_text) +{ + strncpy(text, _text, sizeof(text)-1); + text[sizeof(text) - 1] = '\0'; +} + +void hgeGUIText::printf(const char *format, ...) +{ + va_list vl; + va_start(vl, format); + vsnprintf(text, sizeof(text)-1, format, vl); + va_end(vl); +} + +void hgeGUIText::Render() +{ + font->SetColor(color); + font->Render(tx,ty,align,text); +} + +/* +** hgeGUIButton +*/ + +hgeGUIButton::hgeGUIButton(int _id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty) +{ + id=_id; + bStatic=false; + bVisible=true; + bEnabled=true; + rect.Set(x, y, x+w, y+h); + + bPressed=false; + bTrigger=false; + + sprUp = new hgeSprite(tex, tx, ty, w, h); + sprDown = new hgeSprite(tex, tx+w, ty, w, h); +} + +hgeGUIButton::~hgeGUIButton() +{ + if(sprUp) delete sprUp; + if(sprDown) delete sprDown; +} + +void hgeGUIButton::Render() +{ + if(bPressed) sprDown->Render(rect.x1, rect.y1); + else sprUp->Render(rect.x1, rect.y1); +} + +bool hgeGUIButton::MouseLButton(bool bDown) +{ + if(bDown) + { + bOldState=bPressed; bPressed=true; + return false; + } + else + { + if(bTrigger) bPressed=!bOldState; + else bPressed=false; + return true; + } +} + +/* +** hgeGUISlider +*/ + +hgeGUISlider::hgeGUISlider(int _id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty, float sw, float sh, bool vertical) +{ + id=_id; + bStatic=false; + bVisible=true; + bEnabled=true; + bPressed=false; + bVertical=vertical; + rect.Set(x, y, x+w, y+h); + + mode=HGESLIDER_BAR; + fMin=0; fMax=100; fVal=50; + sl_w=sw; sl_h=sh; + + sprSlider=new hgeSprite(tex, tx, ty, sw, sh); +} + +hgeGUISlider::~hgeGUISlider() +{ + if(sprSlider) delete sprSlider; +} + +void hgeGUISlider::SetValue(float _fVal) +{ + if(_fVal<fMin) fVal=fMin; + else if(_fVal>fMax) fVal=fMax; + else fVal=_fVal; +} + +void hgeGUISlider::Render() +{ + float xx, yy; + float x1,y1,x2,y2; + + xx=rect.x1+(rect.x2-rect.x1)*(fVal-fMin)/(fMax-fMin); + yy=rect.y1+(rect.y2-rect.y1)*(fVal-fMin)/(fMax-fMin); + + if(bVertical) + switch(mode) + { + case HGESLIDER_BAR: x1=rect.x1; y1=rect.y1; x2=rect.x2; y2=yy; break; + case HGESLIDER_BARRELATIVE: x1=rect.x1; y1=(rect.y1+rect.y2)/2; x2=rect.x2; y2=yy; break; + case HGESLIDER_SLIDER: x1=(rect.x1+rect.x2-sl_w)/2; y1=yy-sl_h/2; x2=(rect.x1+rect.x2+sl_w)/2; y2=yy+sl_h/2; break; + } + else + switch(mode) + { + case HGESLIDER_BAR: x1=rect.x1; y1=rect.y1; x2=xx; y2=rect.y2; break; + case HGESLIDER_BARRELATIVE: x1=(rect.x1+rect.x2)/2; y1=rect.y1; x2=xx; y2=rect.y2; break; + case HGESLIDER_SLIDER: x1=xx-sl_w/2; y1=(rect.y1+rect.y2-sl_h)/2; x2=xx+sl_w/2; y2=(rect.y1+rect.y2+sl_h)/2; break; + } + + sprSlider->RenderStretch(x1, y1, x2, y2); +} + +bool hgeGUISlider::MouseLButton(bool bDown) +{ + bPressed=bDown; + return false; +} + +bool hgeGUISlider::MouseMove(float x, float y) +{ + if(bPressed) + { + if(bVertical) + { + if(y>rect.y2-rect.y1) y=rect.y2-rect.y1; + if(y<0) y=0; + fVal=fMin+(fMax-fMin)*y/(rect.y2-rect.y1); + } + else + { + if(x>rect.x2-rect.x1) x=rect.x2-rect.x1; + if(x<0) x=0; + fVal=fMin+(fMax-fMin)*x/(rect.x2-rect.x1); + } + return true; + } + + return false; +} + + +/* +** hgeGUIListbox +*/ + +hgeGUIListbox::hgeGUIListbox(int _id, float x, float y, float w, float h, hgeFont *fnt, DWORD tColor, DWORD thColor, DWORD hColor) +{ + id=_id; + bStatic=false; + bVisible=true; + bEnabled=true; + rect.Set(x, y, x+w, y+h); + font=fnt; + sprHighlight=new hgeSprite(0, 0, 0, w, fnt->GetHeight()); + sprHighlight->SetColor(hColor); + textColor=tColor; + texthilColor=thColor; + pItems=0; + nItems=0; + + nSelectedItem=0; + nTopItem=0; + mx=0; my=0; +} + +hgeGUIListbox::~hgeGUIListbox() +{ + Clear(); + if(sprHighlight) delete sprHighlight; +} + + +int hgeGUIListbox::AddItem(char *item) +{ + hgeGUIListboxItem *pItem=pItems, *pPrev=0, *pNew; + + pNew = new hgeGUIListboxItem; + memcpy(pNew->text, item, min(sizeof(pNew->text), strlen(item)+1)); + pNew->text[sizeof(pNew->text)-1]='\0'; + pNew->next=0; + + while(pItem) { pPrev=pItem; pItem=pItem->next; } + + if(pPrev) pPrev->next=pNew; + else pItems=pNew; + nItems++; + + return nItems-1; +} + +void hgeGUIListbox::DeleteItem(int n) +{ + int i; + hgeGUIListboxItem *pItem=pItems, *pPrev=0; + + if(n<0 || n>=GetNumItems()) return; + + for(i=0;i<n;i++) { pPrev=pItem; pItem=pItem->next; } + + if(pPrev) pPrev->next=pItem->next; + else pItems=pItem->next; + + delete pItem; + nItems--; +} + +char *hgeGUIListbox::GetItemText(int n) +{ + int i; + hgeGUIListboxItem *pItem=pItems; + + if(n<0 || n>=GetNumItems()) return 0; + + for(i=0;i<n;i++) pItem=pItem->next; + + return pItem->text; +} + +void hgeGUIListbox::Clear() +{ + hgeGUIListboxItem *pItem=pItems, *pNext; + + while(pItem) + { + pNext=pItem->next; + delete pItem; + pItem=pNext; + } + + pItems=0; + nItems=0; +} + +void hgeGUIListbox::Render() +{ + int i; + hgeGUIListboxItem *pItem=pItems; + + for(i=0;i<nTopItem;i++) pItem=pItem->next; + for(i=0;i<GetNumRows();i++) + { + if(i>=nItems) return; + + if(nTopItem+i == nSelectedItem) + { + sprHighlight->Render(rect.x1,rect.y1+i*font->GetHeight()); + font->SetColor(texthilColor); + } + else + font->SetColor(textColor); + + font->Render(rect.x1+3, rect.y1+i*font->GetHeight(), HGETEXT_LEFT, pItem->text); + pItem=pItem->next; + } +} + +bool hgeGUIListbox::MouseLButton(bool bDown) +{ + int nItem; + + if(bDown) + { + nItem=nTopItem+int(my)/int(font->GetHeight()); + if(nItem<nItems) + { + nSelectedItem=nItem; + return true; + } + } + return false; +} + + +bool hgeGUIListbox::MouseWheel(int nNotches) +{ + nTopItem-=nNotches; + if(nTopItem<0) nTopItem=0; + if(nTopItem>GetNumItems()-GetNumRows()) nTopItem=GetNumItems()-GetNumRows(); + + return true; +} + +bool hgeGUIListbox::KeyClick(int key, int chr) +{ + switch(key) + { + case HGEK_DOWN: + if(nSelectedItem < nItems-1) + { + nSelectedItem++; + if(nSelectedItem > nTopItem+GetNumRows()-1) nTopItem=nSelectedItem-GetNumRows()+1; + return true; + } + break; + + case HGEK_UP: + if(nSelectedItem > 0) + { + nSelectedItem--; + if(nSelectedItem < nTopItem) nTopItem=nSelectedItem; + return true; + } + break; + } + return false; +} diff --git a/archive/hgehelp/hgeparticle.cpp b/archive/hgehelp/hgeparticle.cpp new file mode 100644 index 0000000..d0d054d --- /dev/null +++ b/archive/hgehelp/hgeparticle.cpp @@ -0,0 +1,311 @@ +// PLEASE NOTE that this is not the 1.81 version of hgeparticle.cpp ... +// the game I'm working on used an older HGE that breaks with the 1.81 +// particle system. If you want 1.81, add the "byteswap" stuff to it. --ryan. + +/* +** Haaf's Game Engine 1.61 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeParticleSystem helper class implementation +*/ + + +#include "hgeparticle.h" + +HGE *hgeParticleSystem::hge=0; + +hgeParticleSystem::hgeParticleSystem(const char *filename, hgeSprite *sprite, float fps) +{ + void *psi; + + hge=hgeCreate(HGE_VERSION); + + psi=hge->Resource_Load(filename); + if(!psi) return; + + char *ptr = (char *) psi; + memset(&info, '\0', sizeof (info)); + info.sprite = sprite; + ptr += 4; // skip these bytes. + +#ifdef WIN32 +#define BYTESWAP(a) +#endif + #define SETMEMBER(typ, x) \ + { info.x = *((const typ *) ptr); ptr += sizeof (typ); BYTESWAP(info.x); } + SETMEMBER(int, nEmission); + SETMEMBER(float, fLifetime); + SETMEMBER(float, fParticleLifeMin); + SETMEMBER(float, fParticleLifeMax); + SETMEMBER(float, fDirection); + SETMEMBER(float, fSpread); + SETMEMBER(BYTE, bRelative); + ptr += 3; // padding. + SETMEMBER(float, fSpeedMin); + SETMEMBER(float, fSpeedMax); + SETMEMBER(float, fGravityMin); + SETMEMBER(float, fGravityMax); + SETMEMBER(float, fRadialAccelMin); + SETMEMBER(float, fRadialAccelMax); + SETMEMBER(float, fTangentialAccelMin); + SETMEMBER(float, fTangentialAccelMax); + SETMEMBER(float, fSizeStart); + SETMEMBER(float, fSizeEnd); + SETMEMBER(float, fSizeVar); + SETMEMBER(float, fSpinStart); + SETMEMBER(float, fSpinEnd); + SETMEMBER(float, fSpinVar); + SETMEMBER(float, colColorStart.r); + SETMEMBER(float, colColorStart.g); + SETMEMBER(float, colColorStart.b); + SETMEMBER(float, colColorStart.a); + SETMEMBER(float, colColorEnd.r); + SETMEMBER(float, colColorEnd.g); + SETMEMBER(float, colColorEnd.b); + SETMEMBER(float, colColorEnd.a); + SETMEMBER(float, fColorVar); + SETMEMBER(float, fAlphaVar); + #undef SETMEMBER + + hge->Resource_Free(psi); + + vecLocation.x=vecPrevLocation.x=0.0f; + vecLocation.y=vecPrevLocation.y=0.0f; + fTx=fTy=0; + + fEmissionResidue=0.0f; + nParticlesAlive=0; + fAge=-2.0; + if(fps!=0.0f) fUpdSpeed=1.0f/fps; + else fUpdSpeed=0.0f; + fResidue=0.0f; + + rectBoundingBox.Clear(); + bUpdateBoundingBox=false; +} + +hgeParticleSystem::hgeParticleSystem(hgeParticleSystemInfo *psi, float fps) +{ + hge=hgeCreate(HGE_VERSION); + + memcpy(&info, psi, sizeof(hgeParticleSystemInfo)); + + vecLocation.x=vecPrevLocation.x=0.0f; + vecLocation.y=vecPrevLocation.y=0.0f; + fTx=fTy=0; + + fEmissionResidue=0.0f; + nParticlesAlive=0; + fAge=-2.0; + if(fps!=0.0f) fUpdSpeed=1.0f/fps; + else fUpdSpeed=0.0f; + fResidue=0.0f; + + rectBoundingBox.Clear(); + bUpdateBoundingBox=false; +} + +hgeParticleSystem::hgeParticleSystem(const hgeParticleSystem &ps) +{ + memcpy(this, &ps, sizeof(hgeParticleSystem)); + hge=hgeCreate(HGE_VERSION); +} + +void hgeParticleSystem::Update(float fDeltaTime) +{ + if(fUpdSpeed==0.0f) _update(fDeltaTime); + else + { + fResidue+=fDeltaTime; + if(fResidue>=fUpdSpeed) + { + _update(fUpdSpeed); + while(fResidue>=fUpdSpeed) fResidue-=fUpdSpeed; + } + } +} + +void hgeParticleSystem::_update(float fDeltaTime) +{ + int i; + float ang; + hgeParticle *par; + hgeVector vecAccel, vecAccel2; + + if(fAge >= 0) + { + fAge += fDeltaTime; + if(fAge >= info.fLifetime) fAge = -2.0f; + } + + // update all alive particles + + if(bUpdateBoundingBox) rectBoundingBox.Clear(); + par=particles; + + for(i=0; i<nParticlesAlive; i++) + { + par->fAge += fDeltaTime; + if(par->fAge >= par->fTerminalAge) + { + nParticlesAlive--; + memcpy(par, &particles[nParticlesAlive], sizeof(hgeParticle)); + i--; + continue; + } + + vecAccel = par->vecLocation-vecLocation; + vecAccel.Normalize(); + vecAccel2 = vecAccel; + vecAccel *= par->fRadialAccel; + + // vecAccel2.Rotate(M_PI_2); + // the following is faster + ang = vecAccel2.x; + vecAccel2.x = -vecAccel2.y; + vecAccel2.y = ang; + + vecAccel2 *= par->fTangentialAccel; + par->vecVelocity += (vecAccel+vecAccel2)*fDeltaTime; + par->vecVelocity.y += par->fGravity*fDeltaTime; + + par->vecLocation += par->vecVelocity; + + par->fSpin += par->fSpinDelta*fDeltaTime; + par->fSize += par->fSizeDelta*fDeltaTime; + par->colColor += par->colColorDelta*fDeltaTime; + + if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y); + + par++; + } + + // generate new particles + + if(fAge != -2.0f) + { + float fParticlesNeeded = info.nEmission*fDeltaTime + fEmissionResidue; + int nParticlesCreated = (unsigned int)fParticlesNeeded; + fEmissionResidue=fParticlesNeeded-nParticlesCreated; + + par=&particles[nParticlesAlive]; + + for(i=0; i<nParticlesCreated; i++) + { + if(nParticlesAlive>=MAX_PARTICLES) break; + + par->fAge = 0.0f; + par->fTerminalAge = hge->Random_Float(info.fParticleLifeMin, info.fParticleLifeMax); + + par->vecLocation = vecPrevLocation+(vecLocation-vecPrevLocation)*hge->Random_Float(0.0f, 1.0f); + par->vecLocation.x += hge->Random_Float(-2.0f, 2.0f); + par->vecLocation.y += hge->Random_Float(-2.0f, 2.0f); + + ang=info.fDirection-M_PI_2+hge->Random_Float(0,info.fSpread)-info.fSpread/2.0f; + if(info.bRelative) ang += (vecPrevLocation-vecLocation).Angle()+M_PI_2; + par->vecVelocity.x = cosf(ang); + par->vecVelocity.y = sinf(ang); + par->vecVelocity *= hge->Random_Float(info.fSpeedMin, info.fSpeedMax); + + par->fGravity = hge->Random_Float(info.fGravityMin, info.fGravityMax); + par->fRadialAccel = hge->Random_Float(info.fRadialAccelMin, info.fRadialAccelMax); + par->fTangentialAccel = hge->Random_Float(info.fTangentialAccelMin, info.fTangentialAccelMax); + + par->fSize = hge->Random_Float(info.fSizeStart, info.fSizeStart+(info.fSizeEnd-info.fSizeStart)*info.fSizeVar); + par->fSizeDelta = (info.fSizeEnd-par->fSize) / par->fTerminalAge; + + par->fSpin = hge->Random_Float(info.fSpinStart, info.fSpinStart+(info.fSpinEnd-info.fSpinStart)*info.fSpinVar); + par->fSpinDelta = (info.fSpinEnd-par->fSpin) / par->fTerminalAge; + + par->colColor.r = hge->Random_Float(info.colColorStart.r, info.colColorStart.r+(info.colColorEnd.r-info.colColorStart.r)*info.fColorVar); + par->colColor.g = hge->Random_Float(info.colColorStart.g, info.colColorStart.g+(info.colColorEnd.g-info.colColorStart.g)*info.fColorVar); + par->colColor.b = hge->Random_Float(info.colColorStart.b, info.colColorStart.b+(info.colColorEnd.b-info.colColorStart.b)*info.fColorVar); + par->colColor.a = hge->Random_Float(info.colColorStart.a, info.colColorStart.a+(info.colColorEnd.a-info.colColorStart.a)*info.fAlphaVar); + + par->colColorDelta.r = (info.colColorEnd.r-par->colColor.r) / par->fTerminalAge; + par->colColorDelta.g = (info.colColorEnd.g-par->colColor.g) / par->fTerminalAge; + par->colColorDelta.b = (info.colColorEnd.b-par->colColor.b) / par->fTerminalAge; + par->colColorDelta.a = (info.colColorEnd.a-par->colColor.a) / par->fTerminalAge; + + if(bUpdateBoundingBox) rectBoundingBox.Encapsulate(par->vecLocation.x, par->vecLocation.y); + + nParticlesAlive++; + par++; + } + } + + vecPrevLocation=vecLocation; +} + +void hgeParticleSystem::MoveTo(float x, float y, bool bMoveParticles) +{ + int i; + float dx,dy; + + if(bMoveParticles) + { + dx=x-vecLocation.x; + dy=y-vecLocation.y; + + for(i=0;i<nParticlesAlive;i++) + { + particles[i].vecLocation.x += dx; + particles[i].vecLocation.y += dy; + } + + vecPrevLocation.x=vecPrevLocation.x + dx; + vecPrevLocation.y=vecPrevLocation.y + dy; + } + else + { + if(fAge==-2.0) { vecPrevLocation.x=x; vecPrevLocation.y=y; } + else { vecPrevLocation.x=vecLocation.x; vecPrevLocation.y=vecLocation.y; } + } + + vecLocation.x=x; + vecLocation.y=y; +} + +void hgeParticleSystem::FireAt(float x, float y) +{ + Stop(); + MoveTo(x,y); + Fire(); +} + +void hgeParticleSystem::Fire() +{ + if(info.fLifetime==-1.0f) fAge=-1.0f; + else fAge=0.0f; + fResidue=0.0; +} + +void hgeParticleSystem::Stop(bool bKillParticles) +{ + fAge=-2.0f; + if(bKillParticles) + { + nParticlesAlive=0; + rectBoundingBox.Clear(); + } +} + +void hgeParticleSystem::Render() +{ + int i; + DWORD col; + hgeParticle *par=particles; + + col=info.sprite->GetColor(); + + for(i=0; i<nParticlesAlive; i++) + { + info.sprite->SetColor(par->colColor.GetHWColor()); + info.sprite->RenderEx(par->vecLocation.x+fTx, par->vecLocation.y+fTy, par->fSpin*par->fAge, par->fSize); + par++; + } + + info.sprite->SetColor(col); +} + diff --git a/archive/hgehelp/hgepmanager.cpp b/archive/hgehelp/hgepmanager.cpp new file mode 100644 index 0000000..16a0b1d --- /dev/null +++ b/archive/hgehelp/hgepmanager.cpp @@ -0,0 +1,96 @@ +// PLEASE NOTE that this is not the 1.81 version of hgeparticle.cpp ... +// the game I'm working on used an older HGE that breaks with the 1.81 +// particle system. If you want 1.81, just overwrite this file. --ryan. + +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeParticleManager helper class implementation +*/ + + +#include "hgeparticle.h" + + +hgeParticleManager::hgeParticleManager(const float fps) +{ + nPS=0; + fFPS=fps; + tX=tY=0.0f; +} + +hgeParticleManager::~hgeParticleManager() +{ + int i; + for(i=0;i<nPS;i++) delete psList[i]; +} + +void hgeParticleManager::Update(float dt) +{ + int i; + for(i=0;i<nPS;i++) + { + psList[i]->Update(dt); + if(psList[i]->GetAge()==-2.0f && psList[i]->GetParticlesAlive()==0) + { + delete psList[i]; + psList[i]=psList[nPS-1]; + nPS--; + i--; + } + } +} + +void hgeParticleManager::Render() +{ + int i; + for(i=0;i<nPS;i++) psList[i]->Render(); +} + +hgeParticleSystem* hgeParticleManager::SpawnPS(hgeParticleSystemInfo *psi, float x, float y) +{ + if(nPS==MAX_PSYSTEMS) return 0; + psList[nPS]=new hgeParticleSystem(psi,fFPS); + psList[nPS]->FireAt(x,y); + psList[nPS]->Transpose(tX,tY); + nPS++; + return psList[nPS-1]; +} + +bool hgeParticleManager::IsPSAlive(hgeParticleSystem *ps) const +{ + int i; + for(i=0;i<nPS;i++) if(psList[i]==ps) return true; + return false; +} + +void hgeParticleManager::Transpose(float x, float y) +{ + int i; + for(i=0;i<nPS;i++) psList[i]->Transpose(x,y); + tX=x; tY=y; +} + +void hgeParticleManager::KillPS(hgeParticleSystem *ps) +{ + int i; + for(i=0;i<nPS;i++) + { + if(psList[i]==ps) + { + delete psList[i]; + psList[i]=psList[nPS-1]; + nPS--; + return; + } + } +} + +void hgeParticleManager::KillAll() +{ + int i; + for(i=0;i<nPS;i++) delete psList[i]; + nPS=0; +} diff --git a/archive/hgehelp/hgerect.cpp b/archive/hgehelp/hgerect.cpp new file mode 100644 index 0000000..303286c --- /dev/null +++ b/archive/hgehelp/hgerect.cpp @@ -0,0 +1,45 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeRect helper class implementation +*/ + + +#include "hgerect.h" +#include <math.h> + + +void hgeRect::Encapsulate(float x, float y) +{ + if(bClean) + { + x1=x2=x; + y1=y2=y; + bClean=false; + } + else + { + if(x<x1) x1=x; + if(x>x2) x2=x; + if(y<y1) y1=y; + if(y>y2) y2=y; + } +} + +bool hgeRect::TestPoint(float x, float y) const +{ + if(x>=x1 && x<x2 && y>=y1 && y<y2) return true; + + return false; +} + +bool hgeRect::Intersect(const hgeRect *rect) const +{ + if(fabs(x1 + x2 - rect->x1 - rect->x2) < (x2 - x1 + rect->x2 - rect->x1)) + if(fabs(y1 + y2 - rect->y1 - rect->y2) < (y2 - y1 + rect->y2 - rect->y1)) + return true; + + return false; +} diff --git a/archive/hgehelp/hgeresource.cpp b/archive/hgehelp/hgeresource.cpp new file mode 100644 index 0000000..e681369 --- /dev/null +++ b/archive/hgehelp/hgeresource.cpp @@ -0,0 +1,254 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager helper class implementation +*/ + + +#include "hgeresource.h" +#include "parser.h" +#include "resources.h" + + +HGE *hgeResourceManager::hge=0; + + +hgeResourceManager::hgeResourceManager(const char *scriptname) +{ + hge=hgeCreate(HGE_VERSION); + + for(int i=0;i<RESTYPES;i++) res[i]=0; + _parse_script(scriptname); +} + +hgeResourceManager::~hgeResourceManager() +{ + _remove_all(); + hge->Release(); +} + +void hgeResourceManager::_parse_script(const char *scriptname) +{ + ResDesc *rc, *rcnext; + + if(scriptname) + { + RScript::Parse(this, NULL, scriptname, NULL); + + rc=res[RES_SCRIPT]; + while(rc) + { + rc->Free(); + rcnext=rc->next; + delete rc; + rc=rcnext; + } + res[RES_SCRIPT]=0; + } +} + +void hgeResourceManager::_remove_all() +{ + int i; + ResDesc *rc, *rcnext; + + for(i=0;i<RESTYPES;i++) + { + rc=res[i]; + while(rc) + { + rc->Free(); + rcnext=rc->next; + delete rc; + rc=rcnext; + } + res[i]=0; + } +} + +void hgeResourceManager::ChangeScript(const char *scriptname) +{ + _remove_all(); + _parse_script(scriptname); +} + +bool hgeResourceManager::Precache(int groupid) +{ + int i; + ResDesc *rc; + bool bResult=true; + + for(i=0;i<RESTYPES;i++) + { + rc=res[i]; + while(rc) + { + if(!groupid || groupid==rc->resgroup) bResult=bResult && (rc->Get(this)!=0); + rc=rc->next; + } + } + + return bResult; +} + +void hgeResourceManager::Purge(int groupid) +{ + int i; + ResDesc *rc; + + for(i=0;i<RESTYPES;i++) + { + rc=res[i]; + while(rc) + { + if(!groupid || groupid==rc->resgroup) rc->Free(); + rc=rc->next; + } + } +} + +void* hgeResourceManager::GetResource(const char *name, int resgroup) +{ + void *reshandle; + RResource *resource; + ResDesc *Res=FindRes(this, RES_RESOURCE, name); + + if(Res) return (void *)Res->Get(this); + else + { + reshandle=hge->Resource_Load(name); + if(reshandle) + { + resource=new RResource(); + resource->handle=(size_t)reshandle; + resource->resgroup=resgroup; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_RESOURCE, resource); + + return reshandle; + } + } + + return 0; +} + +HTEXTURE hgeResourceManager::GetTexture(const char *name, int resgroup) +{ + HTEXTURE reshandle; + RTexture *resource; + ResDesc *Res=FindRes(this, RES_TEXTURE, name); + if(Res) return (HTEXTURE)Res->Get(this); + else + { + reshandle=hge->Texture_Load(name); + if(reshandle) + { + resource=new RTexture(); + resource->handle=reshandle; + resource->resgroup=resgroup; + resource->mipmap=false; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_TEXTURE, resource); + + return reshandle; + } + } + + return 0; +} + +HEFFECT hgeResourceManager::GetEffect(const char *name, int resgroup) +{ + HEFFECT reshandle; + REffect *resource; + ResDesc *Res=FindRes(this, RES_EFFECT, name); + if(Res) return (HEFFECT)Res->Get(this); + else + { + reshandle=hge->Effect_Load(name); + if(reshandle) + { + resource=new REffect(); + resource->handle=reshandle; + resource->resgroup=resgroup; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_EFFECT, resource); + + return reshandle; + } + } + + return 0; +} + +HTARGET hgeResourceManager::GetTarget(const char *name) +{ + ResDesc *Res=FindRes(this, RES_TARGET, name); + if(Res) return (HTARGET)Res->Get(this); + else return 0; +} + +hgeSprite* hgeResourceManager::GetSprite(const char *name) +{ + ResDesc *Res=FindRes(this, RES_SPRITE, name); + if(Res) return (hgeSprite *)Res->Get(this); + else return 0; +} + +hgeAnimation* hgeResourceManager::GetAnimation(const char *name) +{ + ResDesc *Res=FindRes(this, RES_ANIMATION, name); + if(Res) return (hgeAnimation *)Res->Get(this); + else return 0; +} + +hgeFont* hgeResourceManager::GetFont(const char *name) +{ + ResDesc *Res=FindRes(this, RES_FONT, name); + if(Res) return (hgeFont *)Res->Get(this); + else return 0; +} + +hgeParticleSystem* hgeResourceManager::GetParticleSystem(const char *name) +{ + ResDesc *Res=FindRes(this, RES_PARTICLE, name); + if(Res) return (hgeParticleSystem *)Res->Get(this); + else return 0; +} + +hgeDistortionMesh* hgeResourceManager::GetDistortionMesh(const char *name) +{ + ResDesc *Res=FindRes(this, RES_DISTORT, name); + if(Res) return (hgeDistortionMesh *)Res->Get(this); + else return 0; +} + +hgeStringTable* hgeResourceManager::GetStringTable(const char *name, int resgroup) +{ + hgeStringTable *strtable; + RStringTable *resource; + ResDesc *Res=FindRes(this, RES_STRTABLE, name); + if(Res) return (hgeStringTable*)Res->Get(this); + else + { + strtable=new hgeStringTable(name); + if(strtable) + { + resource=new RStringTable(); + resource->handle=(size_t)strtable; + resource->resgroup=resgroup; + strcpy(resource->name, name); + strcpy(resource->filename, name); + AddRes(this, RES_STRTABLE, resource); + + return strtable; + } + } + + return 0; +} diff --git a/archive/hgehelp/hgesprite.cpp b/archive/hgehelp/hgesprite.cpp new file mode 100644 index 0000000..3ff926f --- /dev/null +++ b/archive/hgehelp/hgesprite.cpp @@ -0,0 +1,302 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeSprite helper class implementation +*/ + + +#include "hgesprite.h" +#include <math.h> + + +HGE *hgeSprite::hge=0; + + +hgeSprite::hgeSprite(HTEXTURE texture, float texx, float texy, float w, float h) +{ + float texx1, texy1, texx2, texy2; + + hge=hgeCreate(HGE_VERSION); + + tx=texx; ty=texy; + width=w; height=h; + + if(texture) + { + tex_width = (float)hge->Texture_GetWidth(texture); + tex_height = (float)hge->Texture_GetHeight(texture); + } + else + { + tex_width = 1.0f; + tex_height = 1.0f; + } + + hotX=0; + hotY=0; + bXFlip=false; + bYFlip=false; + bHSFlip=false; + quad.tex=texture; + + texx1=texx/tex_width; + texy1=texy/tex_height; + texx2=(texx+w)/tex_width; + texy2=(texy+h)/tex_height; + + quad.v[0].tx = texx1; quad.v[0].ty = texy1; + quad.v[1].tx = texx2; quad.v[1].ty = texy1; + quad.v[2].tx = texx2; quad.v[2].ty = texy2; + quad.v[3].tx = texx1; quad.v[3].ty = texy2; + + quad.v[0].z = + quad.v[1].z = + quad.v[2].z = + quad.v[3].z = 0.5f; + + quad.v[0].col = + quad.v[1].col = + quad.v[2].col = + quad.v[3].col = 0xffffffff; + + quad.blend=BLEND_DEFAULT; +} + +hgeSprite::hgeSprite(const hgeSprite &spr) +{ + memcpy(this, &spr, sizeof(hgeSprite)); + hge=hgeCreate(HGE_VERSION); +} + +void hgeSprite::Render(float x, float y) +{ + float tempx1, tempy1, tempx2, tempy2; + + tempx1 = x-hotX; + tempy1 = y-hotY; + tempx2 = x+width-hotX; + tempy2 = y+height-hotY; + + quad.v[0].x = tempx1; quad.v[0].y = tempy1; + quad.v[1].x = tempx2; quad.v[1].y = tempy1; + quad.v[2].x = tempx2; quad.v[2].y = tempy2; + quad.v[3].x = tempx1; quad.v[3].y = tempy2; + + hge->Gfx_RenderQuad(&quad); +} + + +void hgeSprite::RenderEx(float x, float y, float rot, float hscale, float vscale) +{ + float tx1, ty1, tx2, ty2; + float sint, cost; + + if(vscale==0) vscale=hscale; + + tx1 = -hotX*hscale; + ty1 = -hotY*vscale; + tx2 = (width-hotX)*hscale; + ty2 = (height-hotY)*vscale; + + if (rot != 0.0f) + { + cost = cosf(rot); + sint = sinf(rot); + + quad.v[0].x = tx1*cost - ty1*sint + x; + quad.v[0].y = tx1*sint + ty1*cost + y; + + quad.v[1].x = tx2*cost - ty1*sint + x; + quad.v[1].y = tx2*sint + ty1*cost + y; + + quad.v[2].x = tx2*cost - ty2*sint + x; + quad.v[2].y = tx2*sint + ty2*cost + y; + + quad.v[3].x = tx1*cost - ty2*sint + x; + quad.v[3].y = tx1*sint + ty2*cost + y; + } + else + { + quad.v[0].x = tx1 + x; quad.v[0].y = ty1 + y; + quad.v[1].x = tx2 + x; quad.v[1].y = ty1 + y; + quad.v[2].x = tx2 + x; quad.v[2].y = ty2 + y; + quad.v[3].x = tx1 + x; quad.v[3].y = ty2 + y; + } + + hge->Gfx_RenderQuad(&quad); +} + + +void hgeSprite::RenderStretch(float x1, float y1, float x2, float y2) +{ + quad.v[0].x = x1; quad.v[0].y = y1; + quad.v[1].x = x2; quad.v[1].y = y1; + quad.v[2].x = x2; quad.v[2].y = y2; + quad.v[3].x = x1; quad.v[3].y = y2; + + hge->Gfx_RenderQuad(&quad); +} + + +void hgeSprite::Render4V(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) +{ + quad.v[0].x = x0; quad.v[0].y = y0; + quad.v[1].x = x1; quad.v[1].y = y1; + quad.v[2].x = x2; quad.v[2].y = y2; + quad.v[3].x = x3; quad.v[3].y = y3; + + hge->Gfx_RenderQuad(&quad); +} + + +hgeRect* hgeSprite::GetBoundingBoxEx(float x, float y, float rot, float hscale, float vscale, hgeRect *rect) const +{ + float tx1, ty1, tx2, ty2; + float sint, cost; + + rect->Clear(); + + tx1 = -hotX*hscale; + ty1 = -hotY*vscale; + tx2 = (width-hotX)*hscale; + ty2 = (height-hotY)*vscale; + + if (rot != 0.0f) + { + cost = cosf(rot); + sint = sinf(rot); + + rect->Encapsulate(tx1*cost - ty1*sint + x, tx1*sint + ty1*cost + y); + rect->Encapsulate(tx2*cost - ty1*sint + x, tx2*sint + ty1*cost + y); + rect->Encapsulate(tx2*cost - ty2*sint + x, tx2*sint + ty2*cost + y); + rect->Encapsulate(tx1*cost - ty2*sint + x, tx1*sint + ty2*cost + y); + } + else + { + rect->Encapsulate(tx1 + x, ty1 + y); + rect->Encapsulate(tx2 + x, ty1 + y); + rect->Encapsulate(tx2 + x, ty2 + y); + rect->Encapsulate(tx1 + x, ty2 + y); + } + + return rect; +} + +void hgeSprite::SetFlip(bool bX, bool bY, bool bHotSpot) +{ + float tx, ty; + + if(bHSFlip && bXFlip) hotX = width - hotX; + if(bHSFlip && bYFlip) hotY = height - hotY; + + bHSFlip = bHotSpot; + + if(bHSFlip && bXFlip) hotX = width - hotX; + if(bHSFlip && bYFlip) hotY = height - hotY; + + if(bX != bXFlip) + { + tx=quad.v[0].tx; quad.v[0].tx=quad.v[1].tx; quad.v[1].tx=tx; + ty=quad.v[0].ty; quad.v[0].ty=quad.v[1].ty; quad.v[1].ty=ty; + tx=quad.v[3].tx; quad.v[3].tx=quad.v[2].tx; quad.v[2].tx=tx; + ty=quad.v[3].ty; quad.v[3].ty=quad.v[2].ty; quad.v[2].ty=ty; + + bXFlip=!bXFlip; + } + + if(bY != bYFlip) + { + tx=quad.v[0].tx; quad.v[0].tx=quad.v[3].tx; quad.v[3].tx=tx; + ty=quad.v[0].ty; quad.v[0].ty=quad.v[3].ty; quad.v[3].ty=ty; + tx=quad.v[1].tx; quad.v[1].tx=quad.v[2].tx; quad.v[2].tx=tx; + ty=quad.v[1].ty; quad.v[1].ty=quad.v[2].ty; quad.v[2].ty=ty; + + bYFlip=!bYFlip; + } +} + + +void hgeSprite::SetTexture(HTEXTURE tex) +{ + float tx1,ty1,tx2,ty2; + float tw,th; + + quad.tex=tex; + + if(tex) + { + tw = (float)hge->Texture_GetWidth(tex); + th = (float)hge->Texture_GetHeight(tex); + } + else + { + tw = 1.0f; + th = 1.0f; + } + + if(tw!=tex_width || th!=tex_height) + { + tx1=quad.v[0].tx*tex_width; + ty1=quad.v[0].ty*tex_height; + tx2=quad.v[2].tx*tex_width; + ty2=quad.v[2].ty*tex_height; + + tex_width=tw; + tex_height=th; + + tx1/=tw; ty1/=th; + tx2/=tw; ty2/=th; + + quad.v[0].tx=tx1; quad.v[0].ty=ty1; + quad.v[1].tx=tx2; quad.v[1].ty=ty1; + quad.v[2].tx=tx2; quad.v[2].ty=ty2; + quad.v[3].tx=tx1; quad.v[3].ty=ty2; + } +} + + +void hgeSprite::SetTextureRect(float x, float y, float w, float h, bool adjSize) +{ + float tx1, ty1, tx2, ty2; + bool bX,bY,bHS; + + tx=x; + ty=y; + + if(adjSize) + { + width=w; + height=h; + } + + tx1=tx/tex_width; ty1=ty/tex_height; + tx2=(tx+w)/tex_width; ty2=(ty+h)/tex_height; + + quad.v[0].tx=tx1; quad.v[0].ty=ty1; + quad.v[1].tx=tx2; quad.v[1].ty=ty1; + quad.v[2].tx=tx2; quad.v[2].ty=ty2; + quad.v[3].tx=tx1; quad.v[3].ty=ty2; + + bX=bXFlip; bY=bYFlip; bHS=bHSFlip; + bXFlip=false; bYFlip=false; + SetFlip(bX,bY,bHS); +} + + +void hgeSprite::SetColor(DWORD col, int i) +{ + if(i != -1) + quad.v[i].col = col; + else + quad.v[0].col = quad.v[1].col = quad.v[2].col = quad.v[3].col = col; +} + +void hgeSprite::SetZ(float z, int i) +{ + if(i != -1) + quad.v[i].z = z; + else + quad.v[0].z = quad.v[1].z = quad.v[2].z = quad.v[3].z = z; +} diff --git a/archive/hgehelp/hgestrings.cpp b/archive/hgehelp/hgestrings.cpp new file mode 100644 index 0000000..6eda71c --- /dev/null +++ b/archive/hgehelp/hgestrings.cpp @@ -0,0 +1,168 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeStringTable helper class implementation +*/ + + +#include "hgestrings.h" +#include <ctype.h> + +const char STRHEADERTAG[]="[HGESTRINGTABLE]"; +const char STRFORMATERROR[]="String table %s has incorrect format."; + + +HGE *hgeStringTable::hge=0; + + +hgeStringTable::hgeStringTable(const char *filename) +{ + int i; + void *data; + DWORD size; + char *desc, *pdesc; + NamedString *str; + char str_name[MAXSTRNAMELENGTH]; + char *str_value, *pvalue; + + hge=hgeCreate(HGE_VERSION); + strings=0; + + // load string table file + data=hge->Resource_Load(filename, &size); + if(!data) return; + + desc = new char[size+1]; + memcpy(desc,data,size); + desc[size]=0; + hge->Resource_Free(data); + + // check header + if(memcmp(desc, STRHEADERTAG, sizeof(STRHEADERTAG)-1)) + { + hge->System_Log(STRFORMATERROR, filename); + delete[] desc; + return; + } + + pdesc=desc+sizeof(STRHEADERTAG); + str_value=new char[8192]; + + for(;;) + { + // skip whitespaces + while(isspace(*pdesc)) pdesc++; + if(!*pdesc) break; + + // skip comments + if(*pdesc==';') + { + while(*pdesc && *pdesc != '\n') pdesc++; + pdesc++; + continue; + } + + // get string name -> str_name + i=0; + while(pdesc[i] && pdesc[i]!='=' && !isspace(pdesc[i]) && i<MAXSTRNAMELENGTH) + { + str_name[i]=pdesc[i]; + i++; + } + str_name[i]=0; + pdesc+=i; + + // skip string name overflow characters + while(*pdesc && *pdesc!='=' && !isspace(*pdesc)) pdesc++; + if(!*pdesc) break; + + // skip whitespaces to '=' + while(isspace(*pdesc)) pdesc++; + if(*pdesc!='=') { hge->System_Log(STRFORMATERROR, filename); break; } + pdesc++; + + // skip whitespaces to '"' + while(isspace(*pdesc)) pdesc++; + if(*pdesc!='"') { hge->System_Log(STRFORMATERROR, filename); break; } + pdesc++; + + // parse string value till the closing '"' -> str_value + // consider: \", \n, \\, LF, CR, whitespaces at line begin/end + pvalue=str_value; + + while(*pdesc && *pdesc!='"') + { + if(*pdesc=='\n' || *pdesc=='\r') + { + while(isspace(*pdesc)) pdesc++; + + pvalue--; + while(pvalue>=str_value && isspace(*pvalue)) pvalue--; + pvalue++; *pvalue=' '; pvalue++; + + continue; + } + + if(*pdesc=='\\') + { + pdesc++; + if(!*pdesc) continue; + if(*pdesc=='n') *pvalue='\n'; + else *pvalue=*pdesc; + pvalue++; + pdesc++; + continue; + } + + *pvalue=*pdesc; pvalue++; + pdesc++; + } + + *pvalue=0; + + // add the parsed string to the list + str=new NamedString; + strcpy(str->name, str_name); + str->string=new char[strlen(str_value)+1]; + strcpy(str->string, str_value); + str->next=strings; + strings=str; + + if(!*pdesc) break; + pdesc++; + } + + delete[] str_value; + delete[] desc; +} + +hgeStringTable::~hgeStringTable() +{ + NamedString *str, *strnext; + + str=strings; + while(str) + { + strnext=str->next; + delete[] str->string; + delete str; + str=strnext; + } + + hge->Release(); +} + +char *hgeStringTable::GetString(const char *name) +{ + NamedString *str=strings; + + while(str) + { + if(!strcmp(name, str->name)) return str->string; + str=str->next; + } + + return 0; +} diff --git a/archive/hgehelp/hgevector.cpp b/archive/hgehelp/hgevector.cpp new file mode 100644 index 0000000..921f7b7 --- /dev/null +++ b/archive/hgehelp/hgevector.cpp @@ -0,0 +1,69 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeVector helper class implementation +*/ + + +#include "hgevector.h" + +float InvSqrt(float x) +{ + union + { + int intPart; + float floatPart; + } convertor; + + convertor.floatPart = x; + convertor.intPart = 0x5f3759df - (convertor.intPart >> 1); + return convertor.floatPart*(1.5f - 0.4999f*x*convertor.floatPart*convertor.floatPart); +} + +/* +hgeVector *hgeVector::Normalize() +{ + float lenRcp; + + lenRcp=sqrtf(Dot(this)); + + if(lenRcp) + { + lenRcp=1.0f/lenRcp; + + x*=lenRcp; + y*=lenRcp; + } + + return this; +} +*/ + +float hgeVector::Angle(const hgeVector *v) const +{ + if(v) + { + hgeVector s=*this, t=*v; + + s.Normalize(); t.Normalize(); + return acosf(s.Dot(&t)); + } + else return atan2f(y, x); +} + +hgeVector *hgeVector::Rotate(float a) +{ + hgeVector v; + + v.x=x*cosf(a) - y*sinf(a); + v.y=x*sinf(a) + y*cosf(a); + + x=v.x; y=v.y; + + return this; +} + + + diff --git a/archive/hgehelp/parser.cpp b/archive/hgehelp/parser.cpp new file mode 100644 index 0000000..0386ef9 --- /dev/null +++ b/archive/hgehelp/parser.cpp @@ -0,0 +1,209 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Resource script parser implementation +*/ + +#include "parser.h" + + +HGE *RScriptParser::hge=0; + + +struct keyword +{ + const char* word; + int code; +}; + +keyword keytable[]= +{ + { "=", TTEQUALS }, + { ":", TTBASED }, + { ",", TTSEPARATOR }, + { "{", TTOPENBLOCK }, + { "}", TTCLOSEBLOCK }, + { "true", TTBOOL }, + { "false", TTBOOL }, + + { "Include", TTRES_INCLUDE }, + { "Resource", TTRES_RESOURCE }, + { "Texture", TTRES_TEXTURE }, + { "Sound", TTRES_SOUND }, + { "Music", TTRES_MUSIC }, + { "Stream", TTRES_STREAM }, + { "Target", TTRES_TARGET }, + { "Sprite", TTRES_SPRITE }, + { "Animation", TTRES_ANIMATION }, + { "Font", TTRES_FONT }, + { "Particle", TTRES_PARTICLE }, + { "Distortion", TTRES_DISTORT }, + { "StringTable",TTRES_STRTABLE }, + + { "filename", TTPAR_FILENAME }, + { "resgroup", TTPAR_RESGROUP }, + { "mipmap", TTPAR_MIPMAP }, + { "amplify", TTPAR_AMPLIFY }, + { "size", TTPAR_SIZE }, + { "zbuffer", TTPAR_ZBUFFER }, + { "texture", TTPAR_TEXTURE }, + { "rect", TTPAR_RECT }, + { "hotspot", TTPAR_HOTSPOT }, + { "blendmode", TTPAR_BLENDMODE }, + { "color", TTPAR_COLOR }, + { "zorder", TTPAR_ZORDER }, + { "flip", TTPAR_FLIP }, + { "scale", TTPAR_SCALE }, + { "proportion", TTPAR_PROPORTION}, + { "rotation", TTPAR_ROTATION }, + { "frames", TTPAR_FRAMES }, + { "fps", TTPAR_FPS }, + { "mode", TTPAR_MODE }, + { "tracking", TTPAR_TRACKING }, + { "spacing", TTPAR_SPACING }, + { "sprite", TTPAR_SPRITE }, + { "mesh", TTPAR_MESH }, + + { "COLORMUL", TTCON_COLORMUL }, + { "COLORADD", TTCON_COLORADD }, + { "ALPHABLEND", TTCON_ALPHABLND }, + { "ALPHAADD", TTCON_ALPHAADD }, + { "ZWRITE", TTCON_ZWRITE }, + { "NOZWRITE", TTCON_NOZWRITE }, + { "FORWARD", TTCON_FORWARD }, + { "REVERSE", TTCON_REVERSE }, + { "PINGPONG", TTCON_PINGPONG }, + { "NOPINGPONG", TTCON_NOPINGPONG}, + { "LOOP", TTCON_LOOP }, + { "NOLOOP", TTCON_NOLOOP }, + { "CIRCLE", TTCON_CIRCLE }, + { "RECT", TTCON_RECT }, + { "ALPHA", TTCON_ALPHA }, + + { NULL, TTNONE } +}; + +RScriptParser::RScriptParser(char *name, char *scr) +{ + hge=hgeCreate(HGE_VERSION); + + scriptname=name; + script=scr; + tokenvalue[0]=0; + tokentype=TTNONE; + line=1; +} + +int RScriptParser::get_token() +{ + int i; + + // Skip whitespaces and comments + + for(;;) + { + while(*script==' ' || *script=='\t' || *script=='\n' || *script=='\r') + { + if(*script=='\n') line++; + script++; + } + if(*script==';') while(*script && *script!='\n' && *script!='\r') script++; + else break; + } + + // End of script + + if(!*script) { tokentype=TTEND; tokenvalue[0]=0; return tokentype; } + + // Number + + if((*script>='0' && *script<='9') || *script=='.' || *script=='-') + { + tokentype=TTNUMBER; + for(i=0;(*script>='0' && *script<='9') || *script=='.' || *script=='-';i++) + tokenvalue[i]=*script++; + + // Hexadecimal number starting with decimal digit + + if((*script>='A' && *script<='F') || (*script>='a' && *script<='f')) + { + tokentype=TTSTRING; + for(; (*script>='A' && *script<='F') || (*script>='a' && *script<='f') ; i++) + tokenvalue[i]=*script++; + } + + tokenvalue[i]=0; + return tokentype; + } + + // Quoted string + + if(*script=='"') + { + tokentype=TTSTRING; + script++; + for(i=0;*script && *script!='"' && *script!='\n' && *script!='\r';i++) + tokenvalue[i]=*script++; + tokenvalue[i]=0; + if(*script) script++; + return tokentype; + } + + // Keyword + + for(i=0;keytable[i].word;i++) + if(!strtkcmp(keytable[i].word, script)) + { + tokentype = keytable[i].code; + strcpy(tokenvalue,keytable[i].word); + script+=strlen(keytable[i].word); + return tokentype; + } + + // Unquoted string or hexadecimal number + + tokentype=TTSTRING; + for(i=0; + *script && *script!=' ' && *script!='\t' && *script!='\n' && *script!='\r' + && *script!=',' && *script!='=' && *script!='{' && *script!='}' && *script!=':'; + i++) + tokenvalue[i]=*script++; + tokenvalue[i]=0; + return tokentype; +} + +bool RScriptParser::strtkcmp(const char* str, const char* mem) +{ + int i,len=strlen(str); + for(i=0;i<len;i++) + { + if(!mem[i]) return true; + if(mem[i] != str[i]) return true; + } + return false; +} + +DWORD RScriptParser::tkn_hex() +{ + int i; + DWORD dw=0; + char chr; + for(i=0; tokenvalue[i]; i++) + { + chr=tokenvalue[i]; + if(chr >= 'a') chr-='a'-':'; + if(chr >= 'A') chr-='A'-':'; + chr-='0'; + if(chr>0xF) chr=0xF; + dw=(dw << 4) | chr; + } + return dw; +} + +void RScriptParser::ScriptPostError(const char *msg1, const char *msg2) +{ + hge->System_Log("%s, line %d: %s'%s'%s", + get_name(), get_line(), msg1, tokenvalue[0] ? tkn_string():"<EOF>", msg2); +} diff --git a/archive/hgehelp/parser.h b/archive/hgehelp/parser.h new file mode 100644 index 0000000..c33ff11 --- /dev/null +++ b/archive/hgehelp/parser.h @@ -0,0 +1,77 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Resource script parser header +*/ + +#ifndef HGEPARSER_H +#define HGEPARSER_H + + +#include "hge.h" +#include <string.h> +#include <stdlib.h> + + +enum +{ + TTNONE, TTEND, TTNUMBER, TTSTRING, + + TTBOOL, TTEQUALS, TTBASED, TTSEPARATOR, TTOPENBLOCK, TTCLOSEBLOCK, + + TTRES__FIRST, + TTRES_INCLUDE, TTRES_RESOURCE, TTRES_TEXTURE, TTRES_SOUND, TTRES_MUSIC, + TTRES_STREAM, TTRES_TARGET, TTRES_SPRITE, TTRES_ANIMATION, TTRES_FONT, + TTRES_PARTICLE, TTRES_DISTORT, TTRES_STRTABLE, + TTRES__LAST, + + TTPAR__FIRST, + TTPAR_FILENAME, TTPAR_RESGROUP, TTPAR_MIPMAP, TTPAR_AMPLIFY, TTPAR_SIZE, TTPAR_ZBUFFER, + TTPAR_TEXTURE, TTPAR_RECT, TTPAR_HOTSPOT, TTPAR_BLENDMODE, TTPAR_COLOR, + TTPAR_ZORDER, TTPAR_FLIP, TTPAR_SCALE, TTPAR_PROPORTION, TTPAR_ROTATION, TTPAR_FRAMES, + TTPAR_FPS, TTPAR_MODE, TTPAR_TRACKING, TTPAR_SPACING, TTPAR_SPRITE, TTPAR_MESH, + TTPAR__LAST, + + TTCON__FIRST, + TTCON_COLORMUL, TTCON_COLORADD, TTCON_ALPHABLND, TTCON_ALPHAADD, TTCON_ZWRITE, + TTCON_NOZWRITE, TTCON_FORWARD, TTCON_REVERSE, TTCON_PINGPONG, TTCON_NOPINGPONG, + TTCON_LOOP, TTCON_NOLOOP, TTCON_CIRCLE, TTCON_RECT, TTCON_ALPHA, + TTCON__LAST +}; + + +class RScriptParser +{ +public: + RScriptParser(char *name, char *scr); + ~RScriptParser() { hge->Release(); } + + int get_token(); + void put_back() { script-=strlen(tokenvalue); } + int get_line() { return line;} + char* get_name() { return scriptname;} + + char* tkn_string() { return tokenvalue; } + int tkn_int() { return atoi(tokenvalue); } + float tkn_float() { return (float)atof(tokenvalue); } + bool tkn_bool() { return (tokenvalue[0]=='t' || tokenvalue[0]=='T') ? true : false; } + DWORD tkn_hex(); + + void ScriptPostError(const char *msg1, const char *msg2); + + int tokentype; + char tokenvalue[128]; + char* script; + char* scriptname; + int line; + +private: + bool strtkcmp(const char *str, const char *mem); + + static HGE *hge; +}; + + +#endif diff --git a/archive/hgehelp/resources.cpp b/archive/hgehelp/resources.cpp new file mode 100644 index 0000000..33afcaa --- /dev/null +++ b/archive/hgehelp/resources.cpp @@ -0,0 +1,958 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager resources implementation +*/ + + +#include "hgeresource.h" +#include "parser.h" +#include "resources.h" + + +HGE *ResDesc::hge=0; + + +/////////////// COMMON // + +void AddRes(hgeResourceManager *rm, int type, ResDesc *resource) +{ + resource->next=rm->res[type]; + rm->res[type]=resource; +} + +ResDesc *FindRes(hgeResourceManager *rm, int type, const char *name) +{ + ResDesc *rc; + + rc=rm->res[type]; + while(rc) + { + if(!strcmp(name, rc->name)) return rc; + rc=rc->next; + } + + return 0; +} + +bool ScriptSkipToNextParameter(RScriptParser *sp, bool bIgnore) +{ + bool bToBeIgnored=bIgnore; + if(bIgnore) sp->put_back(); + + for(;;) + { + sp->get_token(); + if(sp->tokentype == TTCLOSEBLOCK) { if(bIgnore) {sp->put_back(); return true;} return false; } + if((sp->tokentype > TTRES__FIRST && sp->tokentype < TTRES__LAST) || sp->tokentype == TTEND) + { + sp->put_back(); + if(bIgnore) return true; + sp->ScriptPostError("'}' missed, "," encountered."); + return false; + } + if((sp->tokentype <= TTPAR__FIRST && sp->tokentype >= TTPAR__LAST) || bToBeIgnored) + { + bToBeIgnored=false; + sp->ScriptPostError("Unsupported resource parameter ","."); + do sp->get_token(); + while((sp->tokentype <= TTPAR__FIRST || sp->tokentype >= TTPAR__LAST) && + (sp->tokentype <= TTRES__FIRST || sp->tokentype >= TTRES__LAST) && + sp->tokentype != TTCLOSEBLOCK && sp->tokentype != TTEND); + sp->put_back(); + } + else + { + if(bIgnore) sp->put_back(); + return true; + } + } +} + +void ScriptParseFileResource(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename, ResDesc *rr, int restype) +{ + RResource *rc=(RResource *)rr, *base; + + base = (RResource *)FindRes(rm, restype, basename); + if(base) *rc=*base; else + { + rc->resgroup=0; + rc->filename[0]=0; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp,true); + break; + } + } + + AddRes(rm, restype, rc); +} + +void ScriptParseBlendMode(RScriptParser *sp, int *blend) +{ + for(;;) + { + sp->get_token(); + if(sp->tokentype != TTEQUALS && sp->tokentype != TTSEPARATOR) { sp->put_back(); return; } + + switch(sp->get_token()) + { + case TTCON_COLORMUL: + *blend &= ~BLEND_COLORADD; + break; + + case TTCON_COLORADD: + *blend |= BLEND_COLORADD; + break; + + case TTCON_ALPHABLND: + *blend |= BLEND_ALPHABLEND; + break; + + case TTCON_ALPHAADD: + *blend &= ~BLEND_ALPHABLEND; + break; + + case TTCON_ZWRITE: + *blend |= BLEND_ZWRITE; + break; + + case TTCON_NOZWRITE: + *blend &= ~BLEND_ZWRITE; + break; + + default: + sp->ScriptPostError("Unsupported value ","."); + break; + } + } +} + +void ScriptParseSpriteAnim(RScriptParser *sp, RSprite *rc, bool anim) +{ + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_TEXTURE: + sp->get_token(); sp->get_token(); + strcpy(rc->texname,sp->tkn_string()); + break; + + case TTPAR_RECT: + sp->get_token(); sp->get_token(); + rc->tx=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->ty=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->w=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->h=sp->tkn_float(); + break; + + case TTPAR_HOTSPOT: + sp->get_token(); sp->get_token(); + rc->hotx=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->hoty=sp->tkn_float(); + break; + + case TTPAR_BLENDMODE: + ScriptParseBlendMode(sp, &rc->blend); + break; + + case TTPAR_COLOR: + sp->get_token(); sp->get_token(); + rc->color=sp->tkn_hex(); + break; + + case TTPAR_ZORDER: + sp->get_token(); sp->get_token(); + rc->z=sp->tkn_float(); + break; + + case TTPAR_FLIP: + sp->get_token(); sp->get_token(); + rc->bXFlip=sp->tkn_bool(); + sp->get_token(); sp->get_token(); + rc->bYFlip=sp->tkn_bool(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + case TTPAR_FRAMES: + if(anim) + { + sp->get_token(); sp->get_token(); + ((RAnimation *)rc)->frames=sp->tkn_int(); + break; + } + + case TTPAR_FPS: + if(anim) + { + sp->get_token(); sp->get_token(); + ((RAnimation *)rc)->fps=sp->tkn_float(); + break; + } + + case TTPAR_MODE: + if(anim) + { + for(;;) + { + sp->get_token(); + if(sp->tokentype != TTEQUALS && sp->tokentype != TTSEPARATOR) { sp->put_back(); break; } + + switch(sp->get_token()) + { + case TTCON_FORWARD: + ((RAnimation *)rc)->mode &= ~HGEANIM_REV; + break; + + case TTCON_REVERSE: + ((RAnimation *)rc)->mode |= HGEANIM_REV; + break; + + case TTCON_NOPINGPONG: + ((RAnimation *)rc)->mode &= ~HGEANIM_PINGPONG; + break; + + case TTCON_PINGPONG: + ((RAnimation *)rc)->mode |= HGEANIM_PINGPONG; + break; + + case TTCON_NOLOOP: + ((RAnimation *)rc)->mode &= ~HGEANIM_LOOP; + break; + + case TTCON_LOOP: + ((RAnimation *)rc)->mode |= HGEANIM_LOOP; + break; + + default: + sp->ScriptPostError("Unsupported value ","."); + break; + } + } + break; + } + + default: + ScriptSkipToNextParameter(sp,true); + break; + } + } +} + + +/////////////// RScript // + +void RScript::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *sname, const char *sbasename) +{ + RScriptParser *np; + RScript *res_script; + void *data; + DWORD size; + char *script, name[MAXRESCHARS], basename[MAXRESCHARS]; + int restype; + + if(!FindRes(rm, RES_SCRIPT, sname)) + { + res_script = new RScript(); // hack! we need an instance of RScript to access hge + // if all ok, this object is used later to keep the script + + data=hge->Resource_Load(sname, &size); + if(!data) + { + if(sp) sp->ScriptPostError("Script "," not found."); + else hge->System_Log("Script '%s' not found.",sname); + delete res_script; + return; + } + else + { + script= new char[size+1]; + memcpy(script, data, size); + script[size]=0; + hge->Resource_Free(data); + + strcpy(res_script->name, sname); + AddRes(rm, RES_SCRIPT, res_script); + np = new RScriptParser(res_script->name, script); + + for(;;) + { + np->get_token(); + if(np->tokentype == TTEND) break; + + else if(np->tokentype == TTRES_INCLUDE) + { + np->get_token(); + RScript::Parse(rm, np, np->tkn_string(), NULL); + } + + else if(np->tokentype > TTRES__FIRST && np->tokentype < TTRES__LAST) + { + restype=np->tokentype-TTRES__FIRST-1; + name[0]=basename[0]=0; + + np->get_token(); + if(FindRes(rm, restype, np->tkn_string())) + { + np->ScriptPostError("Resource "," of the same type already has been defined."); + while((np->tokentype <= TTRES__FIRST || np->tokentype >= TTRES__LAST) && np->tokentype != TTEND) np->get_token(); + np->put_back(); + continue; + } + strcpy(name, np->tkn_string()); + + np->get_token(); + + if(np->tokentype == TTBASED) + { + np->get_token(); + if(!FindRes(rm, restype, np->tkn_string())) np->ScriptPostError("Base resource "," is not defined."); + else strcpy(basename, np->tkn_string()); + np->get_token(); + } + + if(np->tokentype == TTOPENBLOCK) + { + switch(restype) + { + case RES_RESOURCE: RResource::Parse(rm, np, name, basename); break; + case RES_TEXTURE: RTexture::Parse(rm, np, name, basename); break; + case RES_EFFECT: REffect::Parse(rm, np, name, basename); break; + case RES_TARGET: RTarget::Parse(rm, np, name, basename); break; + case RES_SPRITE: RSprite::Parse(rm, np, name, basename); break; + case RES_ANIMATION: RAnimation::Parse(rm, np, name, basename); break; + case RES_FONT: RFont::Parse(rm, np, name, basename); break; + case RES_PARTICLE: RParticle::Parse(rm, np, name, basename); break; + case RES_DISTORT: RDistort::Parse(rm, np, name, basename); break; + case RES_STRTABLE: RStringTable::Parse(rm, np, name, basename); break; + } + } + else + { + np->ScriptPostError("Illegal resource syntax, "," found; '{' expected."); + while((np->tokentype <= TTRES__FIRST || np->tokentype >= TTRES__LAST) && np->tokentype != TTEND) np->get_token(); + np->put_back(); + } + } + + else + { + np->ScriptPostError("Unrecognized resource specificator ","."); + while((np->tokentype <= TTRES__FIRST || np->tokentype >= TTRES__LAST) && np->tokentype != TTEND) np->get_token(); + np->put_back(); + } + } + + delete np; + delete[] script; + } + } + else sp->ScriptPostError("Script "," already has been parsed."); +} + +/////////////// RResource // + +void RResource::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + ScriptParseFileResource(rm, sp, name, basename, new RResource(), RES_RESOURCE); +} + +DWORD RResource::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(size_t)hge->Resource_Load(filename); + return handle; +} + +void RResource::Free() +{ + if(handle) hge->Resource_Free((void *)handle); + handle=0; +} + +/////////////// RTexture // + +void RTexture::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RTexture *rc, *base; + + rc=new RTexture(); + base = (RTexture *)FindRes(rm, RES_TEXTURE, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->mipmap=false; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + case TTPAR_MIPMAP: + sp->get_token(); sp->get_token(); + rc->mipmap=sp->tkn_bool(); + break; + + default: + ScriptSkipToNextParameter(sp,true); + break; + } + } + + AddRes(rm, RES_TEXTURE, rc); +} + +DWORD RTexture::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(DWORD)hge->Texture_Load(filename, 0, mipmap); + return handle; +} + +void RTexture::Free() +{ + if(handle) hge->Texture_Free((HTEXTURE)handle); + handle=0; +} + +/////////////// REffect // + +void REffect::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + ScriptParseFileResource(rm, sp, name, basename, new REffect(), RES_EFFECT); +} + +DWORD REffect::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(DWORD)hge->Effect_Load(filename); + return handle; +} + +void REffect::Free() +{ + if(handle) hge->Effect_Free((HEFFECT)handle); + handle=0; +} + +/////////////// RTarget // + +void RTarget::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RTarget *rc, *base; + + rc = new RTarget(); + base = (RTarget *)FindRes(rm, RES_TARGET, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->width=256; + rc->height=256; + rc->zbuffer=false; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp, false)) + { + switch(sp->tokentype) + { + case TTPAR_SIZE: + sp->get_token(); sp->get_token(); + rc->width=sp->tkn_int(); + sp->get_token(); + sp->get_token(); + rc->height=sp->tkn_int(); + break; + + case TTPAR_ZBUFFER: + sp->get_token(); sp->get_token(); + rc->zbuffer=sp->tkn_bool(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_TARGET, rc); +} + +DWORD RTarget::Get(hgeResourceManager *rm) +{ + if(!handle) handle=(DWORD)hge->Target_Create(width, height, zbuffer); + return handle; +} + +void RTarget::Free() +{ + if(handle) hge->Target_Free((HTARGET)handle); + handle=0; +} + +/////////////// RSprite // + +void RSprite::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RSprite *rc, *base; + + rc = new RSprite(); + base = (RSprite *)FindRes(rm, RES_SPRITE, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->texname[0]=0; + rc->tx=rc->ty=0; + rc->w=rc->h=0; + rc->hotx=rc->hoty=0; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + rc->bXFlip=false; + rc->bYFlip=false; +// rc->x=rc->y=0; +// rc->scale=1.0f; +// rc->rotation=0.0f; +// rc->collision=HGECOL_RECT; + } + + rc->handle=0; + strcpy(rc->name, name); + + ScriptParseSpriteAnim(sp, rc, false); + AddRes(rm, RES_SPRITE, rc); +} + +DWORD RSprite::Get(hgeResourceManager *rm) +{ + hgeSprite *spr; + if(!handle) + { + spr = new hgeSprite(rm->GetTexture(texname, resgroup), tx, ty, w, h); + spr->SetColor(color); + spr->SetZ(z); + spr->SetBlendMode(blend); + spr->SetHotSpot(hotx,hoty); + spr->SetFlip(bXFlip, bYFlip); +// spr->MoveTo(x,y); +// spr->SetScale(scale); +// spr->SetRotation(rotation); +// spr->SetCollisionType(collision); + + handle=(size_t)spr; + } + return handle; +} + +void RSprite::Free() +{ + if(handle) delete (hgeSprite *)handle; + handle=0; +} + +/////////////// RAnimation // + +void RAnimation::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RAnimation *rc, *base; + + rc = new RAnimation(); + base = (RAnimation *)FindRes(rm, RES_ANIMATION, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->texname[0]=0; + rc->tx=rc->ty=0; + rc->w=rc->h=0; + rc->hotx=rc->hoty=0; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + rc->bXFlip=false; + rc->bYFlip=false; +// rc->x=rc->y=0; +// rc->scale=1.0f; +// rc->rotation=0.0f; +// rc->collision=HGECOL_RECT; + rc->frames=1; + rc->fps=12.0f; + rc->mode=HGEANIM_FWD | HGEANIM_LOOP; + } + + rc->handle=0; + strcpy(rc->name, name); + + ScriptParseSpriteAnim(sp, rc, true); + AddRes(rm, RES_ANIMATION, rc); +} + +DWORD RAnimation::Get(hgeResourceManager *rm) +{ + hgeAnimation *spr; + if(!handle) + { + spr = new hgeAnimation(rm->GetTexture(texname, resgroup), frames, fps, tx, ty, w, h); + spr->SetColor(color); + spr->SetZ(z); + spr->SetBlendMode(blend); + spr->SetHotSpot(hotx,hoty); + spr->SetFlip(bXFlip, bYFlip); +// spr->MoveTo(x,y); +// spr->SetScale(scale); +// spr->SetRotation(rotation); +// spr->SetCollisionType(collision); + spr->SetMode(mode); + + handle=(size_t)spr; + } + return handle; +} + +void RAnimation::Free() +{ + if(handle) delete (hgeAnimation *)handle; + handle=0; +} + +/////////////// RFont // + +void RFont::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RFont *rc, *base; + + rc = new RFont(); + base = (RFont *)FindRes(rm, RES_FONT, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->mipmap=false; + rc->filename[0]=0; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + rc->scale=1.0f; + rc->proportion=1.0f; + rc->tracking=0.0f; + rc->spacing=1.0f; + rc->rotation=0.0f; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp,false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_BLENDMODE: + ScriptParseBlendMode(sp, &rc->blend); + break; + + case TTPAR_COLOR: + sp->get_token(); sp->get_token(); + rc->color=sp->tkn_hex(); + break; + + case TTPAR_ZORDER: + sp->get_token(); sp->get_token(); + rc->z=sp->tkn_float(); + break; + + case TTPAR_SCALE: + sp->get_token(); sp->get_token(); + rc->scale=sp->tkn_float(); + break; + + case TTPAR_PROPORTION: + sp->get_token(); sp->get_token(); + rc->proportion=sp->tkn_float(); + break; + + case TTPAR_ROTATION: + sp->get_token(); sp->get_token(); + rc->rotation=sp->tkn_float(); + break; + + case TTPAR_TRACKING: + sp->get_token(); sp->get_token(); + rc->tracking=sp->tkn_float(); + break; + + case TTPAR_SPACING: + sp->get_token(); sp->get_token(); + rc->spacing=sp->tkn_float(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + case TTPAR_MIPMAP: + sp->get_token(); sp->get_token(); + rc->mipmap=sp->tkn_bool(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_FONT, rc); +} + +DWORD RFont::Get(hgeResourceManager *rm) +{ + hgeFont *fnt; + if(!handle) + { + fnt = new hgeFont(filename, mipmap); + fnt->SetColor(color); + fnt->SetZ(z); + fnt->SetBlendMode(blend); + fnt->SetScale(scale); + fnt->SetProportion(proportion); + fnt->SetTracking(tracking); + fnt->SetSpacing(spacing); + fnt->SetRotation(rotation); + + handle=(size_t)fnt; + } + return handle; +} + +void RFont::Free() +{ + if(handle) delete (hgeFont *)handle; + handle=0; +} + +/////////////// RParticle // + +void RParticle::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RParticle *rc, *base; + + rc = new RParticle(); + base = (RParticle *)FindRes(rm, RES_PARTICLE, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->filename[0]=0; + rc->spritename[0]=0; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp, false)) + { + switch(sp->tokentype) + { + case TTPAR_FILENAME: + sp->get_token(); sp->get_token(); + strcpy(rc->filename, sp->tkn_string()); + break; + + case TTPAR_SPRITE: + sp->get_token(); sp->get_token(); + strcpy(rc->spritename, sp->tkn_string()); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_PARTICLE, rc); +} + +DWORD RParticle::Get(hgeResourceManager *rm) +{ + hgeParticleSystem *par; + if(!handle) + { + par = new hgeParticleSystem(filename, rm->GetSprite(spritename)); + + handle=(size_t)par; + } + return handle; +} + +void RParticle::Free() +{ + if(handle) delete (hgeParticleSystem *)handle; + handle=0; +} + +/////////////// RDistort // + +void RDistort::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + RDistort *rc, *base; + + rc = new RDistort(); + base = (RDistort *)FindRes(rm, RES_DISTORT, basename); + if(base) *rc=*base; + else + { + rc->resgroup=0; + rc->texname[0]=0; + rc->tx=rc->ty=0; + rc->w=rc->h=0; + rc->cols=rc->rows=2; + rc->blend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE; + rc->color=0xFFFFFFFF; + rc->z=0.5f; + } + rc->handle=0; strcpy(rc->name, name); + + while(ScriptSkipToNextParameter(sp, false)) + { + switch(sp->tokentype) + { + case TTPAR_TEXTURE: + sp->get_token(); sp->get_token(); + strcpy(rc->texname, sp->tkn_string()); + break; + + case TTPAR_RECT: + sp->get_token(); sp->get_token(); + rc->tx=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->ty=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->w=sp->tkn_float(); + sp->get_token(); sp->get_token(); + rc->h=sp->tkn_float(); + break; + + case TTPAR_MESH: + sp->get_token(); sp->get_token(); + rc->cols=sp->tkn_int(); + sp->get_token(); sp->get_token(); + rc->rows=sp->tkn_int(); + break; + + case TTPAR_BLENDMODE: + ScriptParseBlendMode(sp, &rc->blend); + break; + + case TTPAR_COLOR: + sp->get_token(); sp->get_token(); + rc->color=sp->tkn_hex(); + break; + + case TTPAR_ZORDER: + sp->get_token(); sp->get_token(); + rc->z=sp->tkn_float(); + break; + + case TTPAR_RESGROUP: + sp->get_token(); sp->get_token(); + rc->resgroup=sp->tkn_int(); + break; + + default: + ScriptSkipToNextParameter(sp, true); + break; + } + } + + AddRes(rm, RES_DISTORT, rc); +} + +DWORD RDistort::Get(hgeResourceManager *rm) +{ + hgeDistortionMesh *dis; + if(!handle) + { + dis = new hgeDistortionMesh(cols, rows); + dis->SetTexture(rm->GetTexture(texname, resgroup)); + dis->SetTextureRect(tx,ty,w,h); + dis->SetBlendMode(blend); + dis->Clear(color,z); + + handle=(size_t)dis; + } + return handle; +} + +void RDistort::Free() +{ + if(handle) delete (hgeDistortionMesh *)handle; + handle=0; +} + +/////////////// RStringTable // + +void RStringTable::Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename) +{ + ScriptParseFileResource(rm, sp, name, basename, new RStringTable(), RES_STRTABLE); +} + +DWORD RStringTable::Get(hgeResourceManager *rm) +{ + if(!handle) handle = (size_t)new hgeStringTable(filename); + return handle; +} + +void RStringTable::Free() +{ + if(handle) delete (hgeStringTable *)handle; + handle=0; +} diff --git a/archive/hgehelp/resources.h b/archive/hgehelp/resources.h new file mode 100644 index 0000000..8be8384 --- /dev/null +++ b/archive/hgehelp/resources.h @@ -0,0 +1,165 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager resources header +*/ + +#ifndef HGERESOURCES_H +#define HGERESOURCES_H + + +#include "hgeresource.h" +#include "parser.h" + + +#define RES_SCRIPT 0 + +#define RES_RESOURCE 1 +#define RES_TEXTURE 2 +#define RES_EFFECT 3 +#define RES_MUSIC 4 +#define RES_STREAM 5 +#define RES_TARGET 6 +#define RES_SPRITE 7 +#define RES_ANIMATION 8 +#define RES_FONT 9 +#define RES_PARTICLE 10 +#define RES_DISTORT 11 +#define RES_STRTABLE 12 + + +void AddRes(hgeResourceManager *rm, int type, ResDesc *resource); +ResDesc* FindRes(hgeResourceManager *rm, int type, const char *name); + + +struct RScript : public ResDesc +{ + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm) {return 0;} + virtual void Free() {} +}; + +struct RResource : public ResDesc +{ + char filename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RTexture : public ResDesc +{ + char filename[MAXRESCHARS]; + bool mipmap; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct REffect : public ResDesc +{ + char filename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RTarget : public ResDesc +{ + int width; + int height; + bool zbuffer; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RSprite : public ResDesc +{ + char texname[MAXRESCHARS]; + float tx, ty, w, h; + float hotx, hoty; + int blend; + DWORD color; + float z; + bool bXFlip, bYFlip; +// float x,y; +// float scale; +// float rotation; +// int collision; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RAnimation : public RSprite +{ + int frames; + float fps; + int mode; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RFont : public ResDesc +{ + char filename[MAXRESCHARS]; + bool mipmap; + int blend; + DWORD color; + float z; + float scale; + float proportion; + float tracking; + float spacing; + float rotation; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RParticle : public ResDesc +{ + char filename[MAXRESCHARS]; + char spritename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +struct RDistort : public ResDesc +{ + char texname[MAXRESCHARS]; + float tx, ty, w, h; + int cols, rows; + int blend; + DWORD color; + float z; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + + +struct RStringTable : public ResDesc +{ + char filename[MAXRESCHARS]; + + static void Parse(hgeResourceManager *rm, RScriptParser *sp, const char *name, const char *basename); + virtual DWORD Get(hgeResourceManager *rm); + virtual void Free(); +}; + +#endif diff --git a/archive/hgewin/ZLIB/adler32.c b/archive/hgewin/ZLIB/adler32.c new file mode 100644 index 0000000..65ad6a5 --- /dev/null +++ b/archive/hgewin/ZLIB/adler32.c @@ -0,0 +1,169 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2007 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#define local static + +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +local uLong adler32_combine_(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} + +uLong ZEXPORT adler32_combine64(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off64_t len2; +{ + return adler32_combine_(adler1, adler2, len2); +} diff --git a/archive/hgewin/ZLIB/crc32.c b/archive/hgewin/ZLIB/crc32.c new file mode 100644 index 0000000..91be372 --- /dev/null +++ b/archive/hgewin/ZLIB/crc32.c @@ -0,0 +1,442 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include <stdio.h> +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include <limits.h> +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); +local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); + + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + uInt len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +local uLong crc32_combine_(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} + +uLong ZEXPORT crc32_combine64(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off64_t len2; +{ + return crc32_combine_(crc1, crc2, len2); +} diff --git a/archive/hgewin/ZLIB/crc32.h b/archive/hgewin/ZLIB/crc32.h new file mode 100644 index 0000000..8053b61 --- /dev/null +++ b/archive/hgewin/ZLIB/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/archive/hgewin/ZLIB/crypt.h b/archive/hgewin/ZLIB/crypt.h new file mode 100644 index 0000000..c01e587 --- /dev/null +++ b/archive/hgewin/ZLIB/crypt.h @@ -0,0 +1,136 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +This code is a modified version of crypting code in Infozip distribution + +The encryption/decryption parts of this source code (as opposed to the +non-echoing password parts) were originally written in Europe. The +whole source package can be freely distributed, including from the USA. +(Prior to January 2000, re-export from the US was a violation of US law.) + +This encryption code is a direct transcription of the algorithm from +Roger Schlafly, described by Phil Katz in the file appnote.txt. This +file (appnote.txt) is distributed with the PKZIP program (even in the +version without encryption capabilities). + +If you don't need crypting in your application, just define symbols +NOCRYPT and NOUNCRYPT. + +This code support the "Traditional PKWARE Encryption". + +The new AES encryption added on Zip format by Winzip (see the page +http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong +Encryption is not supported. + */ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long *pkeys, const unsigned long *pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys + 2)) &0xffff) | 2; + return (int)(((temp *(temp ^ 1)) >> 8) &0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long *pkeys, const unsigned long *pcrc_32_tab, int c) +{ + (*(pkeys + 0)) = CRC32((*(pkeys + 0)), c); + (*(pkeys + 1)) += (*(pkeys + 0)) &0xff; + (*(pkeys + 1)) = (*(pkeys + 1)) *134775813L + 1; + { + register int keyshift = (int)((*(pkeys + 1)) >> 24); + (*(pkeys + 2)) = CRC32((*(pkeys + 2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char *passwd, unsigned long *pkeys, const unsigned long *pcrc_32_tab) +{ + *(pkeys + 0) = 305419896L; + *(pkeys + 1) = 591751049L; + *(pkeys + 2) = 878082192L; + while (*passwd != '\0') + { + update_keys(pkeys, pcrc_32_tab, (int) *passwd); + passwd++; + } +} + +//------------------------------------------------------------------------- + +#define zdecode(pkeys,pcrc_32_tab,c) \ +(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ +(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + + #define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ + #ifndef ZCR_SEED2 + #define ZCR_SEED2 3141592654UL /* use PI as default pattern */ + #endif + + static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)const char *passwd; /* password string */ + unsigned char *buf; /* where to write header */ + int bufSize; + unsigned long *pkeys; + const unsigned long *pcrc_32_tab; + unsigned long crcForCrypting; + { + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN - 2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize < RAND_HEAD_LEN) + { + return 0; + } + + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the + * output of rand() to get less predictability, since rand() is + * often poorly implemented. + */ + if (++calls == 1) + { + srand((unsigned)(time(NULL) ^ ZCR_SEED2)); + } + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + c = (rand() >> 7) &0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) &0xff, t); + buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) &0xff, t); + return n; + } + +#endif diff --git a/archive/hgewin/ZLIB/deflate.h b/archive/hgewin/ZLIB/deflate.h new file mode 100644 index 0000000..cbf0d1e --- /dev/null +++ b/archive/hgewin/ZLIB/deflate.h @@ -0,0 +1,342 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2010 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + /* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, + ulg stored_len, int last)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch ZLIB_INTERNAL _length_code[]; + extern uch ZLIB_INTERNAL _dist_code[]; +#else + extern const uch ZLIB_INTERNAL _length_code[]; + extern const uch ZLIB_INTERNAL _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/archive/hgewin/ZLIB/inffast.c b/archive/hgewin/ZLIB/inffast.c new file mode 100644 index 0000000..2f1d60b --- /dev/null +++ b/archive/hgewin/ZLIB/inffast.c @@ -0,0 +1,340 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2008, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void ZLIB_INTERNAL inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + PUP(out) = PUP(from); + } while (--len); + continue; + } +#endif + } + from = window - OFF; + if (wnext == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/archive/hgewin/ZLIB/inffast.h b/archive/hgewin/ZLIB/inffast.h new file mode 100644 index 0000000..e5c1aa4 --- /dev/null +++ b/archive/hgewin/ZLIB/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/archive/hgewin/ZLIB/inffixed.h b/archive/hgewin/ZLIB/inffixed.h new file mode 100644 index 0000000..75ed4b5 --- /dev/null +++ b/archive/hgewin/ZLIB/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/archive/hgewin/ZLIB/inflate.c b/archive/hgewin/ZLIB/inflate.c new file mode 100644 index 0000000..a8431ab --- /dev/null +++ b/archive/hgewin/ZLIB/inflate.c @@ -0,0 +1,1480 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateReset2(strm, windowBits) +z_streamp strm; +int windowBits; +{ + int wrap; + struct inflate_state FAR *state; + + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= 15; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { + ZFREE(strm, state->window); + state->window = Z_NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + int ret; + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include <stdio.h> + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + NEEDBITS(here.bits); + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} + +int ZEXPORT inflateUndermine(strm, subvert) +z_streamp strm; +int subvert; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + return Z_OK; +#else + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +long ZEXPORT inflateMark(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} diff --git a/archive/hgewin/ZLIB/inflate.h b/archive/hgewin/ZLIB/inflate.h new file mode 100644 index 0000000..95f4986 --- /dev/null +++ b/archive/hgewin/ZLIB/inflate.h @@ -0,0 +1,122 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2009 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 10K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ +}; diff --git a/archive/hgewin/ZLIB/inftrees.c b/archive/hgewin/ZLIB/inftrees.c new file mode 100644 index 0000000..11e9c52 --- /dev/null +++ b/archive/hgewin/ZLIB/inftrees.c @@ -0,0 +1,330 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used >= ENOUGH_LENS) || + (type == DISTS && used >= ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + here.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = here; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/archive/hgewin/ZLIB/inftrees.h b/archive/hgewin/ZLIB/inftrees.h new file mode 100644 index 0000000..baa53a0 --- /dev/null +++ b/archive/hgewin/ZLIB/inftrees.h @@ -0,0 +1,62 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005, 2010 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1444, which is the sum of 852 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distribtution. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 9 15" for literal/length codes + returns returns 852, and "enough 30 6 15" for distance codes returns 592. + The initial root table size (9 or 6) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 852 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/archive/hgewin/ZLIB/ioapi.c b/archive/hgewin/ZLIB/ioapi.c new file mode 100644 index 0000000..9ac1985 --- /dev/null +++ b/archive/hgewin/ZLIB/ioapi.c @@ -0,0 +1,107 @@ +/* ioapi.c -- IO base function header for compress/uncompress .zip +files using zlib + zip or unzip API + +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "zlib.h" +#include "ioapi.h" + + +void *ZCALLBACK fopen_file_func(void *opaque, const char *filename, int mode) +{ + FILE *file = NULL; + + const char *mode_fopen = NULL; + + if ((mode &ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + { + mode_fopen = "rb"; + } + else + { + if (mode &ZLIB_FILEFUNC_MODE_EXISTING) + { + mode_fopen = "r+b"; + } + else + { + if (mode &ZLIB_FILEFUNC_MODE_CREATE) + { + mode_fopen = "wb"; + } + } + } + + if ((filename != NULL) && (mode_fopen != NULL)) + { + file = fopen(filename, mode_fopen); + } + return file; +} + +//------------------------------------------------------------------------- + + +DWORD ZCALLBACK fread_file_func(void *opaque, void *stream, void *buf, DWORD size) +{ + return fread(buf, 1, (size_t)size, (FILE*)stream); +} + +//------------------------------------------------------------------------- + + +DWORD ZCALLBACK fwrite_file_func(void *opaque, void *stream, const void *buf, DWORD size) +{ + return fwrite(buf, 1, (size_t)size, (FILE*)stream); +} + +//------------------------------------------------------------------------- + +long ZCALLBACK ftell_file_func(void *opaque, void *stream) +{ + return ftell((FILE*)stream); +} + +//------------------------------------------------------------------------- + +long ZCALLBACK fseek_file_func(void *opaque, void *stream, DWORD offset, int origin) +{ + fseek((FILE*)stream, offset, origin); + + return 0; +} + +//------------------------------------------------------------------------- + +int ZCALLBACK fclose_file_func(void *opaque, void *stream) +{ + return fclose((FILE*)stream); +} + +//------------------------------------------------------------------------- + +int ZCALLBACK ferror_file_func(void *opaque, void *stream) +{ + return ferror((FILE*)stream); +} + +//------------------------------------------------------------------------- + +void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/archive/hgewin/ZLIB/ioapi.h b/archive/hgewin/ZLIB/ioapi.h new file mode 100644 index 0000000..b2ffb14 --- /dev/null +++ b/archive/hgewin/ZLIB/ioapi.h @@ -0,0 +1,79 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip +files using zlib + zip or unzip API + +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + */ + +#ifndef _ZLIBIOAPI_H + #define _ZLIBIOAPI_H + + + #define ZLIB_FILEFUNC_MODE_READ (1) + #define ZLIB_FILEFUNC_MODE_WRITE (2) + #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + + #define ZLIB_FILEFUNC_MODE_EXISTING (4) + #define ZLIB_FILEFUNC_MODE_CREATE (8) + + // begin ryan. + #ifndef DWORD + #define DWORD uInt + #endif + #ifndef BYTE + #define BYTE Byte + #endif + // end ryan. + + #ifndef ZCALLBACK + + #if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif + #endif + + #ifdef __cplusplus + extern "C" + { + #endif + + typedef void *(ZCALLBACK *open_file_func)(void *opaque, const char *filename, int mode); + typedef DWORD(ZCALLBACK *read_file_func)(void *opaque, void *stream, void *buf, DWORD size); + typedef DWORD(ZCALLBACK *write_file_func)(void *opaque, void *stream, const void *buf, DWORD size); + typedef DWORD(ZCALLBACK *tell_file_func)(void *opaque, void *stream); + typedef DWORD(ZCALLBACK *seek_file_func)(void *opaque, void *stream, DWORD offset, int origin); + typedef int(ZCALLBACK *close_file_func)(void *opaque, void *stream); + typedef int(ZCALLBACK *testerror_file_func)(void *opaque, void *stream); + + typedef struct zlib_filefunc_def_s + { + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + void *opaque; + } zlib_filefunc_def; + + + + void fill_fopen_filefunc OF((zlib_filefunc_def *pzlib_filefunc_def)); + + #define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) + #define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) + #define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) + #define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) + #define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) + #define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + + + #ifdef __cplusplus + } + #endif + +#endif diff --git a/archive/hgewin/ZLIB/trees.c b/archive/hgewin/ZLIB/trees.c new file mode 100644 index 0000000..56e9bb1 --- /dev/null +++ b/archive/hgewin/ZLIB/trees.c @@ -0,0 +1,1244 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2010 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include <ctype.h> +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local int detect_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (ush)val << s->bi_valid;\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (ush)(value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; +#endif + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1<<extra_lbits[code]); n++) { + _length_code[length++] = (uch)code; + } + } + Assert (length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + _length_code[length-1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<<extra_dbits[code]); n++) { + _dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include <stdio.h> +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ZLIB_INTERNAL _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void ZLIB_INTERNAL _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int last; /* one if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+last, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+last, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ZLIB_INTERNAL _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(s) + deflate_state *s; +{ + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/archive/hgewin/ZLIB/trees.h b/archive/hgewin/ZLIB/trees.h new file mode 100644 index 0000000..d35639d --- /dev/null +++ b/archive/hgewin/ZLIB/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/archive/hgewin/ZLIB/uncompr.c b/archive/hgewin/ZLIB/uncompr.c new file mode 100644 index 0000000..ad98be3 --- /dev/null +++ b/archive/hgewin/ZLIB/uncompr.c @@ -0,0 +1,59 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/archive/hgewin/ZLIB/unzip.c b/archive/hgewin/ZLIB/unzip.c new file mode 100644 index 0000000..868f035 --- /dev/null +++ b/archive/hgewin/ZLIB/unzip.c @@ -0,0 +1,1592 @@ +/* unzip.c -- IO for uncompress .zip files using zlib +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +Read unzip.h for more info + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC + #include <stddef.h> + #include <string.h> + #include <stdlib.h> +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else + #include <errno.h> +#endif + +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO + #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) + #define CASESENSITIVITYDEFAULT_NO + #endif +#endif + + +#ifndef UNZ_BUFSIZE + #define UNZ_BUFSIZE (32768) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP + #define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC + #define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE + #define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ + +typedef struct unz_file_info_internal_s +{ + DWORD offset_curfile; /* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, +when reading and decompress it */ + +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + DWORD pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + DWORD stream_initialised; /* flag set if stream structure is initialised*/ + DWORD offset_local_extrafield; /* offset of the local extra field */ + DWORD size_local_extrafield; /* size of the local extra field */ + DWORD pos_local_extrafield; /* position in the local extra field in read*/ + DWORD crc32; /* crc32 of all data uncompressed */ + DWORD crc32_wait; /* crc32 we must obtain after decompress all */ + DWORD rest_read_compressed; /* number of byte to be decompressed */ + DWORD rest_read_uncompressed; /*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + void *filestream; /* io structore of the zipfile */ + DWORD compression_method; /* compression method (0==store) */ + DWORD byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile + */ +typedef struct +{ + zlib_filefunc_def z_filefunc; + void *filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + DWORD byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + DWORD num_file; /* number of the current file in the zipfile*/ + DWORD pos_in_central_dir; /* pos of the current file in the central dir*/ + DWORD current_file_ok; /* flag about the usability of the current file*/ + DWORD central_pos; /* position of the beginning of the central dir*/ + DWORD size_central_dir; /* size of the central directory */ + DWORD offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s *pfile_in_zip_read; /* structure about the current file if we are decompressing it */ + int encrypted; + + #ifndef NOUNCRYPT + DWORD keys[3]; /* keys defining the pseudo-random sequence */ + const DWORD *pcrc_32_tab; + #endif + +} unz_s; + + +#ifndef NOUNCRYPT + #include "crypt.h" +#endif + +/* =========================================================================== +Read a byte from a gz_stream; update next_in and avail_in. Return EOF +for end of file. +IN assertion: the stream s has been sucessfully opened for reading. + */ + + +static int unzlocal_getByte(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream, int *pi) +{ + BYTE c; + int err = (int)ZREAD(*pzlib_filefunc_def, filestream, &c, 1); + + if (err == 1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def, filestream)) + { + return UNZ_ERRNO; + } + else + { + return UNZ_EOF; + } + } +} + + +/* =========================================================================== +Reads a long in LSB order from the given gz_stream. Sets + */ + +static int unzlocal_getShort(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream, DWORD *pX) +{ + DWORD x; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + + x = (DWORD)i; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + + x += ((DWORD)i) << 8; + + if (err == UNZ_OK) + { + *pX = x; + } + else + { + *pX = 0; + } + + return err; +} + +//------------------------------------------------------------------------- + + +static int unzlocal_getLong(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream, DWORD *pX) +{ + DWORD x; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + x = (DWORD)i; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + x += ((DWORD)i) << 8; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + x += ((DWORD)i) << 16; + + if (err == UNZ_OK) + { + err = unzlocal_getByte(pzlib_filefunc_def, filestream, &i); + } + x += ((DWORD)i) << 24; + + if (err == UNZ_OK) + { + *pX = x; + } + else + { + *pX = 0; + } + return err; +} + + +//------------------------------------------------------------------------- + + +#ifdef CASESENSITIVITYDEFAULT_NO + #define CASESENSITIVITYDEFAULTVALUE 2 +#else + #define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION + #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* +Compare two filename (fileName1,fileName2). +If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) +If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi +or strcasecmp) +If iCaseSenisivity = 0, case sensitivity is defaut of your operating system +(like 1 on Unix, 2 on Windows) +*/ +/* +extern int ZEXPORT unzStringFileNameCompare(const char *fileName1, const char *fileName2, int iCaseSensitivity) +{ + if (iCaseSensitivity == 0) + { + iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; + } + + if (iCaseSensitivity == 1) + { + return strcmp(fileName1, fileName2); + } + + return stricmp(fileName1, fileName2); +} +*/ +//------------------------------------------------------------------------- + +#ifndef BUFREADCOMMENT + #define BUFREADCOMMENT (0x400) +#endif + +/* +Locate the Central directory of a zipfile (at the end, just before +the global comment) + */ + +static DWORD unzlocal_SearchCentralDir(const zlib_filefunc_def *pzlib_filefunc_def, void *filestream) +{ + BYTE *buf; + DWORD uSizeFile; + DWORD uBackRead; + DWORD uMaxBack = 0xffff; /* maximum size of global comment */ + DWORD uPosFound = 0; + + if (ZSEEK(*pzlib_filefunc_def, filestream, 0, SEEK_END) != 0) + { + return 0; + } + + + uSizeFile = ZTELL(*pzlib_filefunc_def, filestream); + + if (uMaxBack > uSizeFile) + { + uMaxBack = uSizeFile; + } + + buf = (BYTE*)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + { + return 0; + } + + uBackRead = 4; + while (uBackRead < uMaxBack) + { + DWORD uReadSize, uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + { + uBackRead = uMaxBack; + } + else + { + uBackRead += BUFREADCOMMENT; + } + uReadPos = uSizeFile - uBackRead; + + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4): (uSizeFile - uReadPos); + if (ZSEEK(*pzlib_filefunc_def, filestream, uReadPos, SEEK_SET) != 0) + { + break; + } + + if (ZREAD(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + { + break; + } + + for (i = (int)uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) + { + uPosFound = uReadPos + i; + break; + } + + if (uPosFound != 0) + { + break; + } + } + TRYFREE(buf); + return uPosFound; +} + +/* +Open a Zip file. path contain the full pathname (by example, +on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer +"zlib/zlib114.zip". +If the zipfile cannot be opened (file doesn't exist or in not valid), the +return value is NULL. +Else, the return value is a unzFile Handle, usable with other function +of this unzip package. + */ +extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def) +{ + unz_s us; + unz_s *s; + DWORD central_pos, uL; + + DWORD number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + DWORD number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + DWORD number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err = UNZ_OK; + + if (pzlib_filefunc_def == NULL) + { + fill_fopen_filefunc(&us.z_filefunc); + } + else + { + us.z_filefunc = *pzlib_filefunc_def; + } + + us.filestream = (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream == NULL) + { + return NULL; + } + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc, us.filestream); + if (central_pos == 0) + { + err = UNZ_ERRNO; + } + + if (ZSEEK(us.z_filefunc, us.filestream, central_pos, SEEK_SET) != 0) + { + err = UNZ_ERRNO; + } + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if ((number_entry_CD != us.gi.number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) + { + err = UNZ_BADZIPFILE; + } + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if ((central_pos < us.offset_central_dir + us.size_central_dir) && (err == UNZ_OK)) + { + err = UNZ_BADZIPFILE; + } + + if (err != UNZ_OK) + { + ZCLOSE(us.z_filefunc, us.filestream); + return NULL; + } + + us.byte_before_the_zipfile = central_pos - (us.offset_central_dir + us.size_central_dir); + us.central_pos = central_pos; + us.pfile_in_zip_read = NULL; + us.encrypted = 0; + + + s = (unz_s*)ALLOC(sizeof(unz_s)); + *s = us; + unzGoToFirstFile((unzFile)s); + return (unzFile)s; +} + +//------------------------------------------------------------------------- + + +extern unzFile ZEXPORT unzOpen(const char *path) +{ + return unzOpen2(path, NULL); +} + +/* +Close a ZipFile opened with unzipOpen. +If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), +these files MUST be closed with unzipCloseCurrentFile before call unzipClose. +return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzClose(unzFile file) +{ + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + s = (unz_s*)file; + + if (s->pfile_in_zip_read != NULL) + { + unzCloseCurrentFile(file); + } + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* +Write info about the ZipFile in the *pglobal_info structure. +No preparation of the structure is needed +return UNZ_OK if there is no problem. */ +/* +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info) +{ + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + *pglobal_info = s->gi; + return UNZ_OK; +} +*/ + +/* +Translate date/time from Dos format to tm_unz (readable more easilty) + */ + +static void unzlocal_DosDateToTmuDate(DWORD ulDosDate, tm_unz *ptm) +{ + DWORD uDate; + uDate = (DWORD)(ulDosDate >> 16); + ptm->tm_mday = (DWORD)(uDate &0x1f); + ptm->tm_mon = (DWORD)((((uDate) &0x1E0) / 0x20) - 1); + ptm->tm_year = (DWORD)(((uDate &0x0FE00) / 0x0200) + 1980); + + ptm->tm_hour = (DWORD)((ulDosDate &0xF800) / 0x800); + ptm->tm_min = (DWORD)((ulDosDate &0x7E0) / 0x20); + ptm->tm_sec = (DWORD)(2 *(ulDosDate &0x1f)); +} + +/* +Get Info about the current file in the zipfile, with internal only info + */ + +static int unzlocal_GetCurrentFileInfoInternal(unzFile file, unz_file_info *pfile_info, unz_file_info_internal *pfile_info_internal, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize) +{ + unz_s *s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err = UNZ_OK; + DWORD uMagic; + long lSeek = 0; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + if (ZSEEK(s->z_filefunc, s->filestream, s->pos_in_central_dir + s->byte_before_the_zipfile, SEEK_SET) != 0) + { + err = UNZ_ERRNO; + } + + /* we check the magic */ + + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if (uMagic != 0x02014b50) + { + err = UNZ_BADZIPFILE; + } + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.flag) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.compression_method) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + unzlocal_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.crc) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &file_info.internal_fa) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info.external_fa) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &file_info_internal.offset_curfile) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + lSeek += file_info.size_filename; + + if ((err == UNZ_OK) && (szFileName != NULL)) + { + DWORD uSizeRead; + if (file_info.size_filename < fileNameBufferSize) + { + *(szFileName + file_info.size_filename) = '\0'; + uSizeRead = file_info.size_filename; + } + else + { + uSizeRead = fileNameBufferSize; + } + + if ((file_info.size_filename > 0) && (fileNameBufferSize > 0)) + if (ZREAD(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead) + { + err = UNZ_ERRNO; + } + lSeek -= uSizeRead; + } + + if ((err == UNZ_OK) && (extraField != NULL)) + { + DWORD uSizeRead; + if (file_info.size_file_extra < extraFieldBufferSize) + { + uSizeRead = file_info.size_file_extra; + } + else + { + uSizeRead = extraFieldBufferSize; + } + + if (lSeek != 0) + { + if (ZSEEK(s->z_filefunc, s->filestream, lSeek, SEEK_CUR) == 0) + { + lSeek = 0; + } + else + { + err = UNZ_ERRNO; + } + } + + if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0)) + { + if (ZREAD(s->z_filefunc, s->filestream, extraField, uSizeRead) != uSizeRead) + { + err = UNZ_ERRNO; + } + } + + lSeek += file_info.size_file_extra - uSizeRead; + } + else + { + lSeek += file_info.size_file_extra; + } + + + if ((err == UNZ_OK) && (szComment != NULL)) + { + DWORD uSizeRead; + + if (file_info.size_file_comment < commentBufferSize) + { + *(szComment + file_info.size_file_comment) = '\0'; + uSizeRead = file_info.size_file_comment; + } + else + { + uSizeRead = commentBufferSize; + } + + if (lSeek != 0) + { + if (ZSEEK(s->z_filefunc, s->filestream, lSeek, SEEK_CUR) == 0) + { + lSeek = 0; + } + else + { + err = UNZ_ERRNO; + } + } + + if ((file_info.size_file_comment > 0) && (commentBufferSize > 0)) + { + if (ZREAD(s->z_filefunc, s->filestream, szComment, uSizeRead) != uSizeRead) + { + err = UNZ_ERRNO; + } + } + + lSeek += file_info.size_file_comment - uSizeRead; + } + else + { + lSeek += file_info.size_file_comment; + } + + if ((err == UNZ_OK) && (pfile_info != NULL)) + { + *pfile_info = file_info; + } + + if ((err == UNZ_OK) && (pfile_info_internal != NULL)) + { + *pfile_info_internal = file_info_internal; + } + + return err; +} + + + +/* +Write info about the ZipFile in the *pglobal_info structure. +No preparation of the structure is needed +return UNZ_OK if there is no problem. + */ + +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize); +} + +/* +Set the current file of the zipfile to the first file. +return UNZ_OK if there is no problem + */ + +extern int ZEXPORT unzGoToFirstFile(unzFile file) +{ + int err = UNZ_OK; + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + s->pos_in_central_dir = s->offset_central_dir; + s->num_file = 0; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* +Set the current file of the zipfile to the next file. +return UNZ_OK if there is no problem +return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ + +extern int ZEXPORT unzGoToNextFile(unzFile file) +{ + unz_s *s; + int err; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + if (!s->current_file_ok) + { + return UNZ_END_OF_LIST_OF_FILE; + } + + if (s->gi.number_entry != 0xffff) + { + /* 2^16 files overflow hack */ + if (s->num_file + 1 == s->gi.number_entry) + { + return UNZ_END_OF_LIST_OF_FILE; + } + } + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +extern int ZEXPORT unzGetCurrentFileID(unzFile file, DWORD *file_num, DWORD *pos_in_central_dir) +{ + unz_s *s; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + *file_num = s->num_file; + *pos_in_central_dir = s->pos_in_central_dir; + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFileID(unzFile file, DWORD file_num, DWORD pos_in_central_dir) +{ + unz_s *s; + int err; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + s->num_file = file_num; + s->pos_in_central_dir = pos_in_central_dir; + err = unzlocal_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* +Try locate the file szFileName in the zipfile. +For the iCaseSensitivity signification, see unzipStringFileNameCompare + +return value : +UNZ_OK if the file is found. It becomes the current file. +UNZ_END_OF_LIST_OF_FILE if the file is not found + */ + + + +//------------------------------------------------------------------------- + + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// + */ + +/* +Read the local header of the current zipfile +Check the coherency of the local header and info in the end of central +directory about this file +store in *piSizeVar the size of extra info in local header +(filename and size of extra field data) + */ + +static int unzlocal_CheckCurrentFileCoherencyHeader(unz_s *s, DWORD *piSizeVar, DWORD *poffset_local_extrafield, DWORD *psize_local_extrafield) +{ + DWORD uMagic, uData, uFlags; + DWORD size_filename; + DWORD size_extra_field; + int err = UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + + + if (err == UNZ_OK) + { + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if (uMagic != 0x04034b50) + { + err = UNZ_BADZIPFILE; + } + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method)) + { + err = UNZ_BADZIPFILE; + } + + if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // date/time + { + err = UNZ_ERRNO; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // crc + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) && ((uFlags &8) == 0)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // size compr + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) && ((uFlags &8) == 0)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + // size uncompr + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) && ((uFlags &8) == 0)) + { + err = UNZ_BADZIPFILE; + } + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK) + { + err = UNZ_ERRNO; + } + else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename)) + { + err = UNZ_BADZIPFILE; + } + + *piSizeVar += (DWORD)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK) + { + err = UNZ_ERRNO; + } + + *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (DWORD)size_extra_field; + + *piSizeVar += (DWORD)size_extra_field; + + return err; +} + +/* +Open for reading data the current file in the zipfile. +If there is no error and the file is opened, the return value is UNZ_OK. + */ + +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password) +{ + int err = UNZ_OK; + DWORD iSizeVar; + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + DWORD offset_local_extrafield; // offset of the local extra field + DWORD size_local_extrafield; // size of the local extra field + + #ifndef NOUNCRYPT + char source[12]; + #else + if (password != NULL) + { + return UNZ_PARAMERROR; + } + #endif + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + s = (unz_s*)file; + if (!s->current_file_ok) + { + return UNZ_PARAMERROR; + } + + if (s->pfile_in_zip_read != NULL) + { + unzCloseCurrentFile(file); + } + + if (unzlocal_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK) + { + return UNZ_BADZIPFILE; + } + + pfile_in_zip_read_info = (file_in_zip_read_info_s*)ALLOC(sizeof(file_in_zip_read_info_s)); + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->read_buffer = (char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->raw = raw; + + if (pfile_in_zip_read_info->read_buffer == NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised = 0; + + if (method != NULL) + { + *method = (int)s->cur_file_info.compression_method; + } + + if (level != NULL) + { + *level = 6; + switch (s->cur_file_info.flag &0x06) + { + case 6: + *level = 1; + break; + case 4: + *level = 2; + break; + case 2: + *level = 9; + break; + } + } + + if ((s->cur_file_info.compression_method != 0) && (s->cur_file_info.compression_method != Z_DEFLATED)) + { + err = UNZ_BADZIPFILE; + } + + pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; + pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream = s->filestream; + pfile_in_zip_read_info->z_filefunc = s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method == Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (void*)0; + pfile_in_zip_read_info->stream.next_in = (void*)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = inflateInit2(&pfile_in_zip_read_info->stream, - MAX_WBITS); + if (err == Z_OK) + { + pfile_in_zip_read_info->stream_initialised = 1; + } + else + { + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + + pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size; + pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size; + + + pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (DWORD)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + + #ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password, s->keys, s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile, SEEK_SET) != 0) + { + return UNZ_INTERNALERROR; + } + if (ZREAD(s->z_filefunc, s->filestream, source, 12) < 12) + { + return UNZ_INTERNALERROR; + } + + for (i = 0; i < 12; i++) + { + zdecode(s->keys, s->pcrc_32_tab, source[i]); + } + + s->pfile_in_zip_read->pos_in_zipfile += 12; + s->encrypted = 1; + } + #endif + + + return UNZ_OK; +} + +//------------------------------------------------------------------------- + +extern int ZEXPORT unzOpenCurrentFile(unzFile file) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +//------------------------------------------------------------------------- + +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password) +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +//------------------------------------------------------------------------- + +/* +Read bytes from the current file. +buf contain buffer where data must be copied +len the size of buf. + +return the number of byte copied if somes bytes are copied +return 0 if the end of file was reached +return <0 with error code if there is an error +(UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ +extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, DWORD len) +{ + int err = UNZ_OK; + DWORD iRead = 0; + unz_s *s; + + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + { + return UNZ_END_OF_LIST_OF_FILE; + } + + if (len == 0) + { + return 0; + } + + pfile_in_zip_read_info->stream.next_out = (BYTE*)buf; + pfile_in_zip_read_info->stream.avail_out = (DWORD)len; + + if (len > pfile_in_zip_read_info->rest_read_uncompressed) + { + pfile_in_zip_read_info->stream.avail_out = (DWORD)pfile_in_zip_read_info->rest_read_uncompressed; + } + + while (pfile_in_zip_read_info->stream.avail_out > 0) + { + if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed > 0)) + { + DWORD uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressed < uReadThis) + { + uReadThis = (DWORD)pfile_in_zip_read_info->rest_read_compressed; + } + if (uReadThis == 0) + { + return UNZ_EOF; + } + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis) != uReadThis) + { + return UNZ_ERRNO; + } + + #ifndef NOUNCRYPT + if (s->encrypted) + { + DWORD i; + for (i = 0; i < uReadThis; i++) + { + pfile_in_zip_read_info->read_buffer[i] = zdecode(s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]); + } + } + #endif + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed -= uReadThis; + + pfile_in_zip_read_info->stream.next_in = (BYTE*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (DWORD)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) + { + DWORD uDoCopy, i; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) + { + return (iRead == 0) ? UNZ_EOF : iRead; + } + + if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) + { + uDoCopy = pfile_in_zip_read_info->stream.avail_out; + } + else + { + uDoCopy = pfile_in_zip_read_info->stream.avail_in; + } + + for (i = 0; i < uDoCopy; i++) + { + *(pfile_in_zip_read_info->stream.next_out + i) = *(pfile_in_zip_read_info->stream.next_in + i); + } + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + DWORD uTotalOutBefore, uTotalOutAfter; + const BYTE *bufBefore; + DWORD uOutThis; + int flush = Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + err = inflate(&pfile_in_zip_read_info->stream, flush); + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter - uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, bufBefore, (DWORD)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + + iRead += (DWORD)(uTotalOutAfter - uTotalOutBefore); + + if (err == Z_STREAM_END) + { + return (iRead == 0) ? UNZ_EOF : iRead; + } + + if (err != Z_OK) + { + break; + } + } + } + + if (err == Z_OK) + { + return iRead; + } + return err; +} + + +/* +Give the current position in uncompressed data + */ +/* +extern z_off_t ZEXPORT unztell(unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} +*/ + +/* +return 1 if the end of file was reached, 0 elsewhere + */ +/* +extern int ZEXPORT unzeof(unzFile file) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + { + return 1; + } + else + { + return 0; + } +} +*/ + + +/* +Read extra field from the current file (opened by unzOpenCurrentFile) +This is the local-header version of the extra field (sometimes, there is +more info in the local-header version than in the central-header) + +if buf==NULL, it return the size of the local extra field that can be read + +if buf!=NULL, len is the size of the buffer, the extra header is copied in +buf. +the return value is the number of bytes copied in buf, or (if <0) +the error code + */ +/* +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, DWORD len) +{ + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + DWORD read_now; + DWORD size_to_read; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield); + + if (buf == NULL) + { + return (int)size_to_read; + } + + if (len > size_to_read) + { + read_now = (DWORD)size_to_read; + } + else + { + read_now = (DWORD)len; + } + + if (read_now == 0) + { + return 0; + } + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf, read_now) != read_now) + { + return UNZ_ERRNO; + } + + return (int)read_now; +} +*/ +/* +Close the file in zip opened with unzipOpenCurrentFile +Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ + +extern int ZEXPORT unzCloseCurrentFile(unzFile file) +{ + int err = UNZ_OK; + + unz_s *s; + file_in_zip_read_info_s *pfile_in_zip_read_info; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; + + if (pfile_in_zip_read_info == NULL) + { + return UNZ_PARAMERROR; + } + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + { + err = UNZ_CRCERROR; + } + } + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + + if (pfile_in_zip_read_info->stream_initialised) + { + inflateEnd(&pfile_in_zip_read_info->stream); + } + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read = NULL; + + return err; +} + + +/* +Get the global comment string of the ZipFile, in the szComment buffer. +uSizeBuf is the size of the szComment buffer. +return the number of byte copied or an error code <0 + */ +/* +extern int ZEXPORT unzGetGlobalComment(unzFile file, char *szComment, DWORD uSizeBuf) +{ + //int err = UNZ_OK; + unz_s *s; + DWORD uReadThis; + + if (file == NULL) + { + return UNZ_PARAMERROR; + } + + s = (unz_s*)file; + + uReadThis = uSizeBuf; + + if (uReadThis > s->gi.size_comment) + { + uReadThis = s->gi.size_comment; + } + + if (ZSEEK(s->z_filefunc, s->filestream, s->central_pos + 22, SEEK_SET) != 0) + { + return UNZ_ERRNO; + } + + if (uReadThis > 0) + { + *szComment = '\0'; + + if (ZREAD(s->z_filefunc, s->filestream, szComment, uReadThis) != uReadThis) + { + return UNZ_ERRNO; + } + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + { + *(szComment + s->gi.size_comment) = '\0'; + } + return (int)uReadThis; +} +*/
\ No newline at end of file diff --git a/archive/hgewin/ZLIB/unzip.h b/archive/hgewin/ZLIB/unzip.h new file mode 100644 index 0000000..2a9f26f --- /dev/null +++ b/archive/hgewin/ZLIB/unzip.h @@ -0,0 +1,327 @@ +/* unzip.h -- IO for uncompress .zip files using zlib +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g +WinZip, InfoZip tools and compatible. +Encryption and multi volume ZipFile (span) are not supported. +Old compressions used by old PKZip 1.x are not supported + + +I WAIT FEEDBACK at mail info@winimage.com +Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + +Condition of use and distribution are the same than zlib : + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + + */ + +/* for more info about .ZIP format, see +http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip +http://www.info-zip.org/pub/infozip/doc/ +PkWare has also a specification at : +ftp://ftp.pkware.com/probdesc.zip + */ + +#ifndef _unz_H + #define _unz_H + + #ifdef __cplusplus + extern "C" + { + #endif + + #ifndef _ZLIB_H + #include "zlib.h" + #endif + + #ifndef _ZLIBIOAPI_H + #include "ioapi.h" + #endif + + #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ + typedef struct TagunzFile__ + { + int unused; + } unzFile__; + typedef unzFile__ *unzFile; + #else + typedef void *unzFile; + #endif + + + #define UNZ_OK (0) + #define UNZ_END_OF_LIST_OF_FILE (-100) + #define UNZ_ERRNO (Z_ERRNO) + #define UNZ_EOF (0) + #define UNZ_PARAMERROR (-102) + #define UNZ_BADZIPFILE (-103) + #define UNZ_INTERNALERROR (-104) + #define UNZ_CRCERROR (-105) + + /* tm_unz contain date/time info */ + typedef struct tm_unz_s + { + DWORD tm_sec; /* seconds after the minute - [0,59] */ + DWORD tm_min; /* minutes after the hour - [0,59] */ + DWORD tm_hour; /* hours since midnight - [0,23] */ + DWORD tm_mday; /* day of the month - [1,31] */ + DWORD tm_mon; /* months since January - [0,11] */ + DWORD tm_year; /* years - [1980..2044] */ + } tm_unz; + + /* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ + typedef struct unz_global_info_s + { + DWORD number_entry; /* total number of entries in + the central dir on this disk */ + DWORD size_comment; /* size of the global comment of the zipfile */ + } unz_global_info; + + + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_info_s + { + DWORD version; /* version made by 2 bytes */ + DWORD version_needed; /* version needed to extract 2 bytes */ + DWORD flag; /* general purpose bit flag 2 bytes */ + DWORD compression_method; /* compression method 2 bytes */ + DWORD dosDate; /* last mod file date in Dos fmt 4 bytes */ + DWORD crc; /* crc-32 4 bytes */ + DWORD compressed_size; /* compressed size 4 bytes */ + DWORD uncompressed_size; /* uncompressed size 4 bytes */ + DWORD size_filename; /* filename length 2 bytes */ + DWORD size_file_extra; /* extra field length 2 bytes */ + DWORD size_file_comment; /* file comment length 2 bytes */ + + DWORD disk_num_start; /* disk number start 2 bytes */ + DWORD internal_fa; /* internal file attributes 2 bytes */ + DWORD external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; + } unz_file_info; + + extern int ZEXPORT unzStringFileNameCompare OF((const char *fileName1, const char *fileName2, int iCaseSensitivity)); + /* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + */ + + + extern unzFile ZEXPORT unzOpen(const char *path); + /* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. + */ + + extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def); + /* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) + */ + + extern int ZEXPORT unzClose(unzFile file); + /* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + + extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info); + /* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + + extern int ZEXPORT unzGetGlobalComment(unzFile file, char *szComment, DWORD uSizeBuf); + /* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 + */ + + + /***************************************************************************/ + /* Unzip package allow you browse the directory of the zipfile */ + + extern int ZEXPORT unzGoToFirstFile(unzFile file); + /* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem + */ + + extern int ZEXPORT unzGoToNextFile(unzFile file); + /* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. + */ + + extern int ZEXPORT unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity); + /* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found + */ + + extern int ZEXPORT unzGetCurrentFileID(unzFile file, DWORD *file_num, DWORD *pos_in_central_dir); + extern int ZEXPORT unzGoToFileID(unzFile file, DWORD file_num, DWORD pos_in_central_dir); + + /* ****************************************** */ + /* Ryan supplied functions */ + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_pos_s + { + DWORD pos_in_zip_directory; /* offset in zip file directory */ + DWORD num_of_file; /* # of file */ + } unz_file_pos; + + extern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos); + + extern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos); + + /* ****************************************** */ + + extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *szFileName, DWORD fileNameBufferSize, void *extraField, DWORD extraFieldBufferSize, char *szComment, DWORD commentBufferSize); + /* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) + */ + + /***************************************************************************/ + /* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + + extern int ZEXPORT unzOpenCurrentFile(unzFile file); + /* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password); + /* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. + */ + + extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw); + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password); + /* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL + */ + + + extern int ZEXPORT unzCloseCurrentFile(unzFile file); + /* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good + */ + + extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, DWORD len); + /* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) + */ + + extern z_off_t ZEXPORT unztell(unzFile file); + /* + Give the current position in uncompressed data + */ + + extern int ZEXPORT unzeof(unzFile file); + /* + return 1 if the end of file was reached, 0 elsewhere + */ + + extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, DWORD len); + /* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code + */ + + /***************************************************************************/ + + /* Get the current file offset */ + extern DWORD ZEXPORT unzGetOffset(unzFile file); + + /* Set the current file offset */ + extern int ZEXPORT unzSetOffset(unzFile file, DWORD pos); + + + + #ifdef __cplusplus + } + #endif + +#endif /* _unz_H */ diff --git a/archive/hgewin/ZLIB/zconf.h b/archive/hgewin/ZLIB/zconf.h new file mode 100644 index 0000000..02ce56c --- /dev/null +++ b/archive/hgewin/ZLIB/zconf.h @@ -0,0 +1,428 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress +# define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef STDC +# include <sys/types.h> /* for off_t */ +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include <unistd.h> /* for SEEK_* and off_t */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/archive/hgewin/ZLIB/zconf.in.h b/archive/hgewin/ZLIB/zconf.in.h new file mode 100644 index 0000000..91a0f73 --- /dev/null +++ b/archive/hgewin/ZLIB/zconf.in.h @@ -0,0 +1,323 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.in.h,v 1.1 2005/11/23 14:29:59 stingerx Exp $ */ + +#ifndef ZCONF_H + #define ZCONF_H + + /* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ + #ifdef Z_PREFIX + #define deflateInit_ z_deflateInit_ + #define deflate z_deflate + #define deflateEnd z_deflateEnd + #define inflateInit_ z_inflateInit_ + #define inflate z_inflate + #define inflateEnd z_inflateEnd + #define deflateInit2_ z_deflateInit2_ + #define deflateSetDictionary z_deflateSetDictionary + #define deflateCopy z_deflateCopy + #define deflateReset z_deflateReset + #define deflatePrime z_deflatePrime + #define deflateParams z_deflateParams + #define deflateBound z_deflateBound + #define inflateInit2_ z_inflateInit2_ + #define inflateSetDictionary z_inflateSetDictionary + #define inflateSync z_inflateSync + #define inflateSyncPoint z_inflateSyncPoint + #define inflateCopy z_inflateCopy + #define inflateReset z_inflateReset + #define compress z_compress + #define compress2 z_compress2 + #define compressBound z_compressBound + #define uncompress z_uncompress + #define adler32 z_adler32 + #define crc32 z_crc32 + #define get_crc_table z_get_crc_table + + #define Byte z_Byte + #define uInt z_uInt + #define uLong z_uLong + #define Bytef z_Bytef + #define charf z_charf + #define intf z_intf + #define uIntf z_uIntf + #define uLongf z_uLongf + #define voidpf z_voidpf + #define voidp z_voidp + #endif + + #if defined(__MSDOS__) && !defined(MSDOS) + #define MSDOS + #endif + #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) + #define OS2 + #endif + #if defined(_WINDOWS) && !defined(WINDOWS) + #define WINDOWS + #endif + #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) + #define WIN32 + #endif + #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) + #if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) + #ifndef SYS16BIT + #define SYS16BIT + #endif + #endif + #endif + + /* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ + #ifdef SYS16BIT + #define MAXSEG_64K + #endif + #ifdef MSDOS + #define UNALIGNED_OK + #endif + + #ifdef __STDC_VERSION__ + #ifndef STDC + #define STDC + #endif + #if __STDC_VERSION__ >= 199901L + #ifndef STDC99 + #define STDC99 + #endif + #endif + #endif + #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) + #define STDC + #endif + #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) + #define STDC + #endif + #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) + #define STDC + #endif + #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) + #define STDC + #endif + + #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ + #define STDC + #endif + + #ifndef STDC + #ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ + #define const /* note: need a more gentle solution here */ + #endif + #endif + + /* Some Mac compilers merge all .h files incorrectly: */ + #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) + #define NO_DUMMY_DECL + #endif + + /* Maximum value for memLevel in deflateInit2 */ + #ifndef MAX_MEM_LEVEL + #ifdef MAXSEG_64K + #define MAX_MEM_LEVEL 8 + #else + #define MAX_MEM_LEVEL 9 + #endif + #endif + + /* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ + #ifndef MAX_WBITS + #define MAX_WBITS 15 /* 32K LZ77 window */ + #endif + + /* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. + */ + + /* Type declarations */ + + #ifndef OF /* function prototypes */ + #ifdef STDC + #define OF(args) args + #else + #define OF(args) () + #endif + #endif + + /* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ + #ifdef SYS16BIT + #if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ + #define SMALL_MEDIUM + #ifdef _MSC_VER + #define FAR _far + #else + #define FAR far + #endif + #endif + #if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ + #define SMALL_MEDIUM + #ifdef __BORLANDC__ + #define FAR _far + #else + #define FAR far + #endif + #endif + #endif + + #if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ + #ifdef ZLIB_DLL + #if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) + #ifdef ZLIB_INTERNAL + #define ZEXTERN extern __declspec(dllexport) + #else + #define ZEXTERN extern __declspec(dllimport) + #endif + #endif + #endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ + #ifdef ZLIB_WINAPI + #ifdef FAR + #undef FAR + #endif + #include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ + #define ZEXPORT WINAPI + #ifdef WIN32 + #define ZEXPORTVA WINAPIV + #else + #define ZEXPORTVA FAR CDECL + #endif + #endif + #endif + + #if defined (__BEOS__) + #ifdef ZLIB_DLL + #ifdef ZLIB_INTERNAL + #define ZEXPORT __declspec(dllexport) + #define ZEXPORTVA __declspec(dllexport) + #else + #define ZEXPORT __declspec(dllimport) + #define ZEXPORTVA __declspec(dllimport) + #endif + #endif + #endif + + #ifndef ZEXTERN + #define ZEXTERN extern + #endif + #ifndef ZEXPORT + #define ZEXPORT + #endif + #ifndef ZEXPORTVA + #define ZEXPORTVA + #endif + + #ifndef FAR + #define FAR + #endif + + #if !defined(__MACTYPES__) + typedef unsigned char Byte; /* 8 bits */ + #endif + typedef unsigned int uInt; /* 16 bits or more */ + typedef unsigned long uLong; /* 32 bits or more */ + + #ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ + #define Bytef Byte FAR + #else + typedef Byte FAR Bytef; + #endif + typedef char FAR charf; + typedef int FAR intf; + typedef uInt FAR uIntf; + typedef uLong FAR uLongf; + + #ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; + #else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; + #endif + + #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ + #include <sys/types.h> /* for off_t */ + #include <unistd.h> /* for SEEK_* and off_t */ + #ifdef VMS + #include <unixio.h> /* for off_t */ + #endif + #define z_off_t off_t + #endif + #ifndef SEEK_SET + #define SEEK_SET 0 /* Seek from beginning of file. */ + #define SEEK_CUR 1 /* Seek from current position. */ + #define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ + #endif + #ifndef z_off_t + #define z_off_t long + #endif + + #if defined(__OS400__) + #define NO_vsnprintf + #endif + + #if defined(__MVS__) + #define NO_vsnprintf + #ifdef FAR + #undef FAR + #endif + #endif + + /* MVS linker does not support external names larger than 8 bytes */ + #if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") + #endif + +#endif /* ZCONF_H */ diff --git a/archive/hgewin/ZLIB/zip.h b/archive/hgewin/ZLIB/zip.h new file mode 100644 index 0000000..944ed78 --- /dev/null +++ b/archive/hgewin/ZLIB/zip.h @@ -0,0 +1,196 @@ +/* zip.h -- IO for compress .zip files using zlib +Version 1.01, May 8th, 2004 + +Copyright (C) 1998-2004 Gilles Vollant + +This unzip package allow creates .ZIP file, compatible with PKZip 2.04g +WinZip, InfoZip tools and compatible. +Encryption and multi volume ZipFile (span) are not supported. +Old compressions used by old PKZip 1.x are not supported + +For uncompress .zip file, look at unzip.h + + +I WAIT FEEDBACK at mail info@winimage.com +Visit also http://www.winimage.com/zLibDll/unzip.html for evolution + +Condition of use and distribution are the same than zlib : + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + + */ + +/* for more info about .ZIP format, see +http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip +http://www.info-zip.org/pub/infozip/doc/ +PkWare has also a specification at : +ftp://ftp.pkware.com/probdesc.zip + */ + +#ifndef _zip_H + #define _zip_H + + #ifdef __cplusplus + extern "C" + { + #endif + + #ifndef _ZLIB_H + #include "zlib.h" + #endif + + #ifndef _ZLIBIOAPI_H + #include "ioapi.h" + #endif + + #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) + /* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ + typedef struct TagzipFile__ + { + int unused; + } zipFile__; + typedef zipFile__ *zipFile; + #else + typedef voidp zipFile; + #endif + + #define ZIP_OK (0) + #define ZIP_EOF (0) + #define ZIP_ERRNO (Z_ERRNO) + #define ZIP_PARAMERROR (-102) + #define ZIP_BADZIPFILE (-103) + #define ZIP_INTERNALERROR (-104) + + #ifndef DEF_MEM_LEVEL + #if MAX_MEM_LEVEL >= 8 + #define DEF_MEM_LEVEL 8 + #else + #define DEF_MEM_LEVEL MAX_MEM_LEVEL + #endif + #endif + /* default memLevel */ + + /* tm_zip contain date/time info */ + typedef struct tm_zip_s + { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ + } tm_zip; + + typedef struct + { + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ + /* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + } zip_fileinfo; + + typedef const char *zipcharpc; + + + #define APPEND_STATUS_CREATE (0) + #define APPEND_STATUS_CREATEAFTER (1) + #define APPEND_STATUS_ADDINZIP (2) + + extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); + /* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. + */ + + /* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte + */ + + extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, int append, zipcharpc *globalcomment, zlib_filefunc_def *pzlib_filefunc_def)); + + extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level)); + /* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + */ + + + extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw)); + + /* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + + extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, const char *filename, const zip_fileinfo *zipfi, const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global, uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel, int strategy, const char *password, uLong crcForCtypting)); + + /* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCtypting : crc of file to compress (needed for crypting) + */ + + + extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, const void *buf, unsigned len)); + /* + Write data in the zipfile + */ + + extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); + /* + Close the current file in the zipfile + */ + + extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32)); + /* + Close the current file in the zipfile, for fiel opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size + */ + + extern int ZEXPORT zipClose OF((zipFile file, const char *global_comment)); + /* + Close the zipfile + */ + + #ifdef __cplusplus + } + #endif + +#endif /* _zip_H */ diff --git a/archive/hgewin/ZLIB/zlib.h b/archive/hgewin/ZLIB/zlib.h new file mode 100644 index 0000000..bfbba83 --- /dev/null +++ b/archive/hgewin/ZLIB/zlib.h @@ -0,0 +1,1613 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.5, April 19th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.5" +#define ZLIB_VERNUM 0x1250 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 5 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +/* hack for buggy compilers */ +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; +#endif + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/archive/hgewin/ZLIB/zutil.c b/archive/hgewin/ZLIB/zutil.c new file mode 100644 index 0000000..898ed34 --- /dev/null +++ b/archive/hgewin/ZLIB/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch ((int)(sizeof(uInt))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(uLong))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int ZLIB_INTERNAL z_verbose = verbose; + +void ZLIB_INTERNAL z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void ZLIB_INTERNAL zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int ZLIB_INTERNAL zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void ZLIB_INTERNAL zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void ZLIB_INTERNAL zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/archive/hgewin/ZLIB/zutil.h b/archive/hgewin/ZLIB/zutil.h new file mode 100644 index 0000000..258fa88 --- /dev/null +++ b/archive/hgewin/ZLIB/zutil.h @@ -0,0 +1,274 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) +# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define ZLIB_INTERNAL +#endif + +#include "zlib.h" + +#ifdef STDC +# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +# include <stddef.h> +# endif +# include <string.h> +# include <stdlib.h> +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include <alloc.h> +# endif +# else /* MSC or DJGPP */ +# include <malloc.h> +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 +# include <malloc.h> +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include <unix.h> /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + +#if defined(__BORLANDC__) + #pragma warn -8004 + #pragma warn -8008 + #pragma warn -8066 +#endif + +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> + extern int ZLIB_INTERNAL z_verbose; + extern void ZLIB_INTERNAL z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/archive/hgewin/demo.cpp b/archive/hgewin/demo.cpp new file mode 100644 index 0000000..a8a2ce3 --- /dev/null +++ b/archive/hgewin/demo.cpp @@ -0,0 +1,51 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: HGE splash screen +*/ + + +#include "hge_impl.h" +#include "../loading.h" +#include "hgesprite.h" +//#ifdef DEMO +hgeSprite *SprLoad,*SprRot; +HTEXTURE TLoad,TRot; +int px,py; +float dtime,rot; +void DInit() +{ + px=pHGE->System_GetState(HGE_SCREENWIDTH)/2; + py=pHGE->System_GetState(HGE_SCREENHEIGHT)/2; + TLoad=pHGE->Texture_Load((char *)Loading,sizeof(Loading)); + TRot=pHGE->Texture_Load((char *)LoadCircle,sizeof(LoadCircle)); + SprLoad=new hgeSprite(TLoad,0,0,96,32); + SprRot=new hgeSprite(TRot,0,0,48,46); + SprLoad->SetHotSpot(48,16);SprRot->SetHotSpot(24,23); + dtime=0.0f;rot=0.0f; +} +void DDone() +{ + delete SprLoad;delete SprRot; + pHGE->Texture_Free(TLoad);pHGE->Texture_Free(TRot); +} +bool DFrame() +{ + BYTE alpha; + DWORD col=0x00FFFFFF; + dtime+=pHGE->Timer_GetDelta(); + if (dtime<=0.5)alpha=(BYTE)(dtime/0.5f*255.0f);else alpha=255; + if (dtime<=1.5)rot+=((pHGE->Timer_GetDelta())/0.1f)*M_PI*0.3f; + else rot+=((pHGE->Timer_GetDelta())/0.1f)*M_PI*0.3f*((2.0f-dtime)/0.5f); + SprRot->SetColor(SETA(col,alpha)); + if (dtime>=2)return true; + pHGE->Gfx_BeginScene(); + pHGE->Gfx_Clear(0); + SprLoad->Render(px,py); + SprRot->RenderEx(px-75,py,rot); + pHGE->Gfx_EndScene(); + return false; +} +//#endif diff --git a/archive/hgewin/graphics.cpp b/archive/hgewin/graphics.cpp new file mode 100755 index 0000000..43a5cc1 --- /dev/null +++ b/archive/hgewin/graphics.cpp @@ -0,0 +1,983 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: graphics +** Upgraded to DirectX9 By Chris Xiong, 2013/08/08 +*/ + + +#include "hge_impl.h" +#include <d3d9.h> +#include <d3dx9.h>
+static const char* GRAPHICS_SRC_FN="hge/graphics.cpp"; + +void CALL HGE_Impl::Gfx_Clear(DWORD color) +{ + if(pCurTarget) + { + if(pCurTarget->pDepth) + pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 ); + else + pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 ); + } + else + { + if(bZBuffer) + pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 ); + else + pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 ); + } +} + +void CALL HGE_Impl::Gfx_SetClipping(int x, int y, int w, int h) +{ + D3DVIEWPORT9 vp; + int scr_width, scr_height; + + if(!pCurTarget) { + scr_width=pHGE->System_GetStateInt(HGE_SCREENWIDTH); + scr_height=pHGE->System_GetStateInt(HGE_SCREENHEIGHT); + } + else { + scr_width=Texture_GetWidth((HTEXTURE)pCurTarget->pTex); + scr_height=Texture_GetHeight((HTEXTURE)pCurTarget->pTex); + } + + if(!w) { + vp.X=0; + vp.Y=0; + vp.Width=scr_width; + vp.Height=scr_height; + } + else + { + if(x<0) { w+=x; x=0; } + if(y<0) { h+=y; y=0; } + + if(x+w > scr_width) w=scr_width-x; + if(y+h > scr_height) h=scr_height-y; + + vp.X=x; + vp.Y=y; + vp.Width=w; + vp.Height=h; + } + + vp.MinZ=0.0f; + vp.MaxZ=1.0f; + + _render_batch(); + pD3DDevice->SetViewport(&vp); + + D3DXMATRIX tmp; + D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f); + D3DXMatrixTranslation(&tmp, -0.5f, +0.5f, 0.0f); + D3DXMatrixMultiply(&matProj, &matProj, &tmp); + D3DXMatrixOrthoOffCenterLH(&tmp, (float)vp.X, (float)(vp.X+vp.Width), -((float)(vp.Y+vp.Height)), -((float)vp.Y), vp.MinZ, vp.MaxZ); + D3DXMatrixMultiply(&matProj, &matProj, &tmp); + pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); +} + +void CALL HGE_Impl::Gfx_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale) +{ + D3DXMATRIX tmp; + + if(vscale==0.0f) D3DXMatrixIdentity(&matView); + else + { + D3DXMatrixTranslation(&matView, -x, -y, 0.0f); + D3DXMatrixScaling(&tmp, hscale, vscale, 1.0f); + D3DXMatrixMultiply(&matView, &matView, &tmp); + D3DXMatrixRotationZ(&tmp, -rot); + D3DXMatrixMultiply(&matView, &matView, &tmp); + D3DXMatrixTranslation(&tmp, x+dx, y+dy, 0.0f); + D3DXMatrixMultiply(&matView, &matView, &tmp); + } + + _render_batch(); + pD3DDevice->SetTransform(D3DTS_VIEW, &matView); +} + +bool CALL HGE_Impl::Gfx_BeginScene(HTARGET targ) +{ + LPDIRECT3DSURFACE9 pSurf=0, pDepth=0; + D3DDISPLAYMODE Mode; + CRenderTargetList *target=(CRenderTargetList *)targ; + + HRESULT hr = pD3DDevice->TestCooperativeLevel(); + if (hr == D3DERR_DEVICELOST) return false; + else if (hr == D3DERR_DEVICENOTRESET) + { + if(bWindowed) + { + if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN) + { + _PostError("Can't determine desktop video mode"); + return false; + } + + d3dppW.BackBufferFormat = Mode.Format; + if(_format_id(Mode.Format) < 4) nScreenBPP=16; + else nScreenBPP=32; + } + + if(!_GfxRestore()) return false; + } + + if(VertArray) + { + _PostError("Gfx_BeginScene: Scene is already being rendered"); + return false; + } + + if(target != pCurTarget) + { + if(target) + { + target->pTex->GetSurfaceLevel(0, &pSurf); + pDepth=target->pDepth; + } + else + { + pSurf=pScreenSurf; + pDepth=pScreenDepth; + } + if(FAILED(pD3DDevice->SetRenderTarget(0,pSurf))) + { + if(target) pSurf->Release(); + _PostError("Gfx_BeginScene: Can't set render target"); + return false; + } + if(target) + { + pSurf->Release(); + if(target->pDepth) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); + else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); + _SetProjectionMatrix(target->width, target->height); + } + else + { + if(bZBuffer) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); + else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE ); + _SetProjectionMatrix(nScreenWidth, nScreenHeight); + } + + pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); + D3DXMatrixIdentity(&matView); + pD3DDevice->SetTransform(D3DTS_VIEW, &matView); + + pCurTarget=target; + } + + pD3DDevice->BeginScene(); + pVB->Lock( 0, 0, (VOID**)&VertArray, 0 ); + + return true; +} + +void CALL HGE_Impl::Gfx_EndScene() +{ + _render_batch(true); + pD3DDevice->EndScene(); + if(!pCurTarget) pD3DDevice->Present( NULL, NULL, NULL, NULL ); +} + +void CALL HGE_Impl::Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color, float z) +{ + if(VertArray) + { + if(CurPrimType!=HGEPRIM_LINES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_LINES || CurTexture || CurBlendMode!=BLEND_DEFAULT) + { + _render_batch(); + + CurPrimType=HGEPRIM_LINES; + if(CurBlendMode != BLEND_DEFAULT) _SetBlendMode(BLEND_DEFAULT); + if(CurTexture) { pD3DDevice->SetTexture(0, 0); CurTexture=0; } + } + + int i=nPrim*HGEPRIM_LINES; + VertArray[i].x = x1; VertArray[i+1].x = x2; + VertArray[i].y = y1; VertArray[i+1].y = y2; + VertArray[i].z = VertArray[i+1].z = z; + VertArray[i].col = VertArray[i+1].col = color; + VertArray[i].tx = VertArray[i+1].tx = + VertArray[i].ty = VertArray[i+1].ty = 0.0f; + + nPrim++; + } +} + +void CALL HGE_Impl::Gfx_RenderTriple(const hgeTriple *triple) +{ + if(VertArray) + { + if(CurPrimType!=HGEPRIM_TRIPLES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_TRIPLES || CurTexture!=triple->tex || CurBlendMode!=triple->blend) + { + _render_batch(); + + CurPrimType=HGEPRIM_TRIPLES; + if(CurBlendMode != triple->blend) _SetBlendMode(triple->blend); + if(triple->tex != CurTexture) { + pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)triple->tex ); + CurTexture = triple->tex; + } + } + + memcpy(&VertArray[nPrim*HGEPRIM_TRIPLES], triple->v, sizeof(hgeVertex)*HGEPRIM_TRIPLES); + nPrim++; + } +} + +void CALL HGE_Impl::Gfx_RenderQuad(const hgeQuad *quad) +{ + if(VertArray) + { + if(CurPrimType!=HGEPRIM_QUADS || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_QUADS || CurTexture!=quad->tex || CurBlendMode!=quad->blend) + { + _render_batch(); + + CurPrimType=HGEPRIM_QUADS; + if(CurBlendMode != quad->blend) _SetBlendMode(quad->blend); + if(quad->tex != CurTexture) + { + pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)quad->tex ); + CurTexture = quad->tex; + } + } + + memcpy(&VertArray[nPrim*HGEPRIM_QUADS], quad->v, sizeof(hgeVertex)*HGEPRIM_QUADS); + nPrim++; + } +} + +hgeVertex* CALL HGE_Impl::Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim) +{ + if(VertArray) + { + _render_batch(); + + CurPrimType=prim_type; + if(CurBlendMode != blend) _SetBlendMode(blend); + if(tex != CurTexture) + { + pD3DDevice->SetTexture( 0, (LPDIRECT3DTEXTURE9)tex ); + CurTexture = tex; + } + + *max_prim=VERTEX_BUFFER_SIZE / prim_type; + return VertArray; + } + else return 0; +} + +void CALL HGE_Impl::Gfx_FinishBatch(int nprim) +{ + nPrim=nprim; +} + +HTARGET CALL HGE_Impl::Target_Create(int width, int height, bool zbuffer) +{ + CRenderTargetList *pTarget; + D3DSURFACE_DESC TDesc; + + pTarget = new CRenderTargetList; + pTarget->pTex=0; + pTarget->pDepth=0; + + if(FAILED(D3DXCreateTexture(pD3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, + d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &pTarget->pTex))) + { + _PostError("Can't create render target texture"); + delete pTarget; + return 0; + } + + pTarget->pTex->GetLevelDesc(0, &TDesc); + pTarget->width=TDesc.Width; + pTarget->height=TDesc.Height; + + if(zbuffer) + { + if(FAILED(pD3DDevice->CreateDepthStencilSurface(width, height, + D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, false, &pTarget->pDepth, NULL))) + { + pTarget->pTex->Release(); + _PostError("Can't create render target depth buffer"); + delete pTarget; + return 0; + } + } + + pTarget->next=pTargets; + pTargets=pTarget; + + return (HTARGET)pTarget; +} + +void CALL HGE_Impl::Target_Free(HTARGET target) +{ + CRenderTargetList *pTarget=pTargets, *pPrevTarget=NULL; + + while(pTarget) + { + if((CRenderTargetList *)target == pTarget) + { + if(pPrevTarget) + pPrevTarget->next = pTarget->next; + else + pTargets = pTarget->next; + + if(pTarget->pTex) pTarget->pTex->Release(); + if(pTarget->pDepth) pTarget->pDepth->Release(); + + delete pTarget; + return; + } + + pPrevTarget = pTarget; + pTarget = pTarget->next; + } +} + +HTEXTURE CALL HGE_Impl::Target_GetTexture(HTARGET target) +{ + CRenderTargetList *targ=(CRenderTargetList *)target; + if(target) return (HTEXTURE)targ->pTex; + else return 0; +} + +HTEXTURE CALL HGE_Impl::Texture_Create(int width, int height) +{ + LPDIRECT3DTEXTURE9 pTex; + + if( FAILED( D3DXCreateTexture( pD3DDevice, width, height, + 1, // Mip levels + 0, // Usage + D3DFMT_A8R8G8B8, // Format + D3DPOOL_MANAGED, // Memory pool + &pTex ) ) ) + { + _PostError("Can't create texture"); + return NULL; + } + + return (HTEXTURE)pTex; +} + +HTEXTURE CALL HGE_Impl::Texture_Load(const char *filename, DWORD size, bool bMipmap) +{ + void *data; + DWORD _size; + D3DFORMAT fmt1, fmt2; + LPDIRECT3DTEXTURE9 pTex; + D3DXIMAGE_INFO info; + CTextureList *texItem; + + if(size) { data=(void *)filename; _size=size; } + else + { + data=pHGE->Resource_Load(filename, &_size); + if(!data) return NULL; + } + + if(*(DWORD*)data == 0x20534444) // Compressed DDS format magic number + { + fmt1=D3DFMT_UNKNOWN; + fmt2=D3DFMT_A8R8G8B8; + } + else + { + fmt1=D3DFMT_A8R8G8B8; + fmt2=D3DFMT_UNKNOWN; + } + +// if( FAILED( D3DXCreateTextureFromFileInMemory( pD3DDevice, data, _size, &pTex ) ) ) pTex=NULL; + if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size, + D3DX_DEFAULT, D3DX_DEFAULT, + bMipmap ? 0:1, // Mip levels + 0, // Usage + fmt1, // Format + D3DPOOL_MANAGED, // Memory pool + D3DX_FILTER_NONE, // Filter + D3DX_DEFAULT, // Mip filter + 0, // Color key + &info, NULL, + &pTex ) ) ) + + if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size, + D3DX_DEFAULT, D3DX_DEFAULT, + bMipmap ? 0:1, // Mip levels + 0, // Usage + fmt2, // Format + D3DPOOL_MANAGED, // Memory pool + D3DX_FILTER_NONE, // Filter + D3DX_DEFAULT, // Mip filter + 0, // Color key + &info, NULL, + &pTex ) ) ) + + { + _PostError("Can't create texture"); + if(!size) Resource_Free(data); + return NULL; + } + + if(!size) Resource_Free(data); + + texItem=new CTextureList; + texItem->tex=(HTEXTURE)pTex; + texItem->width=info.Width; + texItem->height=info.Height; + texItem->next=textures; + textures=texItem; + + return (HTEXTURE)pTex; +} + +void CALL HGE_Impl::Texture_Free(HTEXTURE tex) +{ + LPDIRECT3DTEXTURE9 pTex=(LPDIRECT3DTEXTURE9)tex; + CTextureList *texItem=textures, *texPrev=0; + + while(texItem) + { + if(texItem->tex==tex) + { + if(texPrev) texPrev->next=texItem->next; + else textures=texItem->next; + delete texItem; + break; + } + texPrev=texItem; + texItem=texItem->next; + } + if(pTex != NULL) pTex->Release(); +} + +int CALL HGE_Impl::Texture_GetWidth(HTEXTURE tex, bool bOriginal) +{ + D3DSURFACE_DESC TDesc; + LPDIRECT3DTEXTURE9 pTex=(LPDIRECT3DTEXTURE9)tex; + CTextureList *texItem=textures; + + if(bOriginal) + { + while(texItem) + { + if(texItem->tex==tex) return texItem->width; + texItem=texItem->next; + } + return 0; + } + else + { + if(FAILED(pTex->GetLevelDesc(0, &TDesc))) return 0; + else return TDesc.Width; + } +} + + +int CALL HGE_Impl::Texture_GetHeight(HTEXTURE tex, bool bOriginal) +{ + D3DSURFACE_DESC TDesc; + LPDIRECT3DTEXTURE9 pTex=(LPDIRECT3DTEXTURE9)tex; + CTextureList *texItem=textures; + + if(bOriginal) + { + while(texItem) + { + if(texItem->tex==tex) return texItem->height; + texItem=texItem->next; + } + return 0; + } + else + { + if(FAILED(pTex->GetLevelDesc(0, &TDesc))) return 0; + else return TDesc.Height; + } +} + + +DWORD * CALL HGE_Impl::Texture_Lock(HTEXTURE tex, bool bReadOnly, int left, int top, int width, int height) +{ + LPDIRECT3DTEXTURE9 pTex=(LPDIRECT3DTEXTURE9)tex; + D3DSURFACE_DESC TDesc; + D3DLOCKED_RECT TRect; + RECT region, *prec; + int flags; + + pTex->GetLevelDesc(0, &TDesc); + if(TDesc.Format!=D3DFMT_A8R8G8B8 && TDesc.Format!=D3DFMT_X8R8G8B8) return 0; + + if(width && height) + { + region.left=left; + region.top=top; + region.right=left+width; + region.bottom=top+height; + prec=®ion; + } + else prec=0; + + if(bReadOnly) flags=D3DLOCK_READONLY; + else flags=0; + + if(FAILED(pTex->LockRect(0, &TRect, prec, flags))) + { + _PostError("Can't lock texture"); + return 0; + } + + return (DWORD *)TRect.pBits; +} + + +void CALL HGE_Impl::Texture_Unlock(HTEXTURE tex) +{ + LPDIRECT3DTEXTURE9 pTex=(LPDIRECT3DTEXTURE9)tex; + pTex->UnlockRect(0); +} + +//////// Implementation //////// + +void HGE_Impl::_render_batch(bool bEndScene) +{ + if(VertArray) + { + pVB->Unlock(); + + if(nPrim) + { + switch(CurPrimType) + { + case HGEPRIM_QUADS: + pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, nPrim<<2, 0, nPrim<<1); + break; + + case HGEPRIM_TRIPLES: + pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, nPrim); + break; + + case HGEPRIM_LINES: + pD3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, nPrim); + break; + } + + nPrim=0; + } + + if(bEndScene) VertArray = 0; + else pVB->Lock( 0, 0, (VOID**)&VertArray, 0 ); + } +} + +void HGE_Impl::_SetBlendMode(int blend) +{ + if((blend & BLEND_ALPHABLEND) != (CurBlendMode & BLEND_ALPHABLEND)) + { + if(blend & BLEND_ALPHABLEND) pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + else pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + } + + if((blend & BLEND_ZWRITE) != (CurBlendMode & BLEND_ZWRITE)) + { + if(blend & BLEND_ZWRITE) pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + else pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + } + + if((blend & BLEND_COLORADD) != (CurBlendMode & BLEND_COLORADD)) + { + if(blend & BLEND_COLORADD) pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD); + else pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + } + + CurBlendMode = blend; +} + +void HGE_Impl::_SetProjectionMatrix(int width, int height) +{ + D3DXMATRIX tmp; + D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f); + D3DXMatrixTranslation(&tmp, -0.5f, height+0.5f, 0.0f); + D3DXMatrixMultiply(&matProj, &matProj, &tmp); + D3DXMatrixOrthoOffCenterLH(&tmp, 0, (float)width, 0, (float)height, 0.0f, 1.0f); + D3DXMatrixMultiply(&matProj, &matProj, &tmp); +} + +bool HGE_Impl::_GfxInit() +{ + static const char *szFormats[]={"UNKNOWN", "R5G6B5", "X1R5G5B5", "A1R5G5B5", "X8R8G8B8", "A8R8G8B8"}; + D3DADAPTER_IDENTIFIER9 AdID; + D3DDISPLAYMODE Mode; + D3DFORMAT Format=D3DFMT_UNKNOWN; + UINT nModes, i; + +// Init D3D + + pD3D=Direct3DCreate9(D3D_SDK_VERSION); // D3D_SDK_VERSION + if(pD3D==NULL) + { + _PostError("Can't create D3D interface"); + return false; + } + +// Get adapter info + + pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &AdID); + System_Log("%s: D3D Driver: %s",GRAPHICS_SRC_FN,AdID.Driver); + System_Log("%s: Description: %s",GRAPHICS_SRC_FN,AdID.Description); + System_Log("%s: Version: %d.%d.%d.%d", + GRAPHICS_SRC_FN, + HIWORD(AdID.DriverVersion.HighPart), + LOWORD(AdID.DriverVersion.HighPart), + HIWORD(AdID.DriverVersion.LowPart), + LOWORD(AdID.DriverVersion.LowPart)); + +// Set up Windowed presentation parameters + + if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN) + { + _PostError("Can't determine desktop video mode"); + if(bWindowed) return false; + } + + ZeroMemory(&d3dppW, sizeof(d3dppW)); + + d3dppW.BackBufferWidth = nScreenWidth; + d3dppW.BackBufferHeight = nScreenHeight; + d3dppW.BackBufferFormat = Mode.Format; + d3dppW.BackBufferCount = 1; + d3dppW.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dppW.hDeviceWindow = hwnd; + d3dppW.Windowed = TRUE; + + if(nHGEFPS==HGEFPS_VSYNC) { d3dppW.SwapEffect = D3DSWAPEFFECT_COPY; d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; } + else { d3dppW.SwapEffect = D3DSWAPEFFECT_COPY; d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;} + + if(bZBuffer) + { + d3dppW.EnableAutoDepthStencil = TRUE; + d3dppW.AutoDepthStencilFormat = D3DFMT_D16; + } + +// Set up Full Screen presentation parameters + + nModes=pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, Mode.Format); + + for(i=0; i<nModes; i++) + { + pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, Mode.Format, i, &Mode); + if(Mode.Width != (UINT)nScreenWidth || Mode.Height != (UINT)nScreenHeight) continue; + if(nScreenBPP==16 && (_format_id(Mode.Format) > _format_id(D3DFMT_A1R5G5B5))) continue; + if(_format_id(Mode.Format) > _format_id(Format)) Format=Mode.Format; + } + + if(Format == D3DFMT_UNKNOWN) + { + _PostError("Can't find appropriate full screen video mode"); + if(!bWindowed) return false; + } + + ZeroMemory(&d3dppFS, sizeof(d3dppFS)); + + d3dppFS.BackBufferWidth = nScreenWidth; + d3dppFS.BackBufferHeight = nScreenHeight; + d3dppFS.BackBufferFormat = Format; + d3dppFS.BackBufferCount = 1; + d3dppFS.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dppFS.hDeviceWindow = hwnd; + d3dppFS.Windowed = FALSE; + + d3dppFS.SwapEffect = D3DSWAPEFFECT_FLIP; + d3dppFS.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + + if(nHGEFPS==HGEFPS_VSYNC) d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + else d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + + if(bZBuffer) + { + d3dppFS.EnableAutoDepthStencil = TRUE; + d3dppFS.AutoDepthStencilFormat = D3DFMT_D16; + } + + d3dpp = bWindowed ? &d3dppW : &d3dppFS; + + if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16; + else nScreenBPP=32; + +// Create D3D Device + + if( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + d3dpp, &pD3DDevice ) ) ) + { + _PostError("Can't create D3D device"); + return false; + } + + _AdjustWindow(); + + System_Log("%s: Mode: %d x %d x %s\n",GRAPHICS_SRC_FN,nScreenWidth,nScreenHeight,szFormats[_format_id(Format)]); + +// Create vertex batch buffer + + VertArray=0; + textures=0; + +// Init all stuff that can be lost + + _SetProjectionMatrix(nScreenWidth, nScreenHeight); + D3DXMatrixIdentity(&matView); + + if(!_init_lost()) return false; + + Gfx_Clear(0); + + return true; +} + +int HGE_Impl::_format_id(D3DFORMAT fmt) +{ + switch(fmt) { + case D3DFMT_R5G6B5: return 1; + case D3DFMT_X1R5G5B5: return 2; + case D3DFMT_A1R5G5B5: return 3; + case D3DFMT_X8R8G8B8: return 4; + case D3DFMT_A8R8G8B8: return 5; + default: return 0; + } +} + +void HGE_Impl::_AdjustWindow() +{ + RECT *rc; + LONG style; + + if(bWindowed) {rc=&rectW; style=styleW; } + else {rc=&rectFS; style=styleFS; } + SetWindowLong(hwnd, GWL_STYLE, style); + + style=GetWindowLong(hwnd, GWL_EXSTYLE); + if(bWindowed) + { + SetWindowLong(hwnd, GWL_EXSTYLE, style & (~WS_EX_TOPMOST)); + SetWindowPos(hwnd, HWND_NOTOPMOST, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, SWP_FRAMECHANGED); + } + else + { + SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_TOPMOST); + SetWindowPos(hwnd, HWND_TOPMOST, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, SWP_FRAMECHANGED); + } +} + +void HGE_Impl::_Resize(int width, int height) +{ + if(hwndParent) + { + //if(procFocusLostFunc) procFocusLostFunc(); + + d3dppW.BackBufferWidth=width; + d3dppW.BackBufferHeight=height; + nScreenWidth=width; + nScreenHeight=height; + + _SetProjectionMatrix(nScreenWidth, nScreenHeight); + _GfxRestore(); + + //if(procFocusGainFunc) procFocusGainFunc(); + } +} + +void HGE_Impl::_GfxDone() +{ + CRenderTargetList *target=pTargets, *next_target; + + while(textures) Texture_Free(textures->tex); + + if(pScreenSurf) { pScreenSurf->Release(); pScreenSurf=0; } + if(pScreenDepth) { pScreenDepth->Release(); pScreenDepth=0; } + + while(target) + { + if(target->pTex) target->pTex->Release(); + if(target->pDepth) target->pDepth->Release(); + next_target=target->next; + delete target; + target=next_target; + } + pTargets=0; + + if(pIB) + { + pD3DDevice->SetIndices(NULL); + pIB->Release(); + pIB=0; + } + if(pVB) + { + if(VertArray) { pVB->Unlock(); VertArray=0; } + pD3DDevice->SetStreamSource( 0, NULL, 0, sizeof(hgeVertex) ); + pVB->Release(); + pVB=0; + } + if(pD3DDevice) { pD3DDevice->Release(); pD3DDevice=0; } + if(pD3D) { pD3D->Release(); pD3D=0; } +} + + +bool HGE_Impl::_GfxRestore() +{ + CRenderTargetList *target=pTargets; + + //if(!pD3DDevice) return false; + //if(pD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST) return; + + if(pScreenSurf) pScreenSurf->Release(); + if(pScreenDepth) pScreenDepth->Release(); + + while(target) + { + if(target->pTex) target->pTex->Release(); + if(target->pDepth) target->pDepth->Release(); + target=target->next; + } + + if(pIB) + { + pD3DDevice->SetIndices(NULL); + pIB->Release(); + } + if(pVB) + { + pD3DDevice->SetStreamSource( 0, NULL, 0, sizeof(hgeVertex) ); + pVB->Release(); + } + + pD3DDevice->Reset(d3dpp); + + if(!_init_lost()) return false; + + if(procGfxRestoreFunc) return procGfxRestoreFunc(); + + return true; +} + + +bool HGE_Impl::_init_lost() +{ + CRenderTargetList *target=pTargets; + +// Store render target + + pScreenSurf=0; + pScreenDepth=0; + + pD3DDevice->GetRenderTarget(0, &pScreenSurf); + pD3DDevice->GetDepthStencilSurface(&pScreenDepth); + + while(target) + { + if(target->pTex) + D3DXCreateTexture(pD3DDevice, target->width, target->height, 1, D3DUSAGE_RENDERTARGET, + d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &target->pTex); + if(target->pDepth) + pD3DDevice->CreateDepthStencilSurface(target->width, target->height, + D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, false, &target->pDepth, NULL); + target=target->next; + } + +// Create Vertex buffer + + if( FAILED (pD3DDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE*sizeof(hgeVertex), + D3DUSAGE_WRITEONLY, + D3DFVF_HGEVERTEX, + D3DPOOL_DEFAULT, &pVB, NULL))) + { + _PostError("Can't create D3D vertex buffer"); + return false; + } + + pD3DDevice->SetVertexShader( NULL ); + pD3DDevice->SetFVF( D3DFVF_HGEVERTEX ); + pD3DDevice->SetStreamSource( 0, pVB, 0, sizeof(hgeVertex) ); + +// Create and setup Index buffer + + if( FAILED( pD3DDevice->CreateIndexBuffer(VERTEX_BUFFER_SIZE*6/4*sizeof(WORD), + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_DEFAULT, &pIB, NULL))) + { + _PostError("Can't create D3D index buffer"); + return false; + } + + WORD *pIndices, n=0; + if( FAILED( pIB->Lock( 0, 0, (VOID**)&pIndices, 0 ) ) ) + { + _PostError("Can't lock D3D index buffer"); + return false; + } + + for(int i=0; i<VERTEX_BUFFER_SIZE/4; i++) { + *pIndices++=n; + *pIndices++=n+1; + *pIndices++=n+2; + *pIndices++=n+2; + *pIndices++=n+3; + *pIndices++=n; + n+=4; + } + + pIB->Unlock(); + pD3DDevice->SetIndices(pIB); + +// Set common render states + + //pD3DDevice->SetRenderState( D3DRS_LASTPIXEL, FALSE ); + pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); + pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); + + pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); + pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); + pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + + pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); + pD3DDevice->SetRenderState( D3DRS_ALPHAREF, 0x01 ); + pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); + + pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); + pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); + pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); + + pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); + pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); + + pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); + + if(bTextureFilter) + { + pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); + pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); + } + else + { + pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT); + pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT); + } + + nPrim=0; + CurPrimType=HGEPRIM_QUADS; + CurBlendMode = BLEND_DEFAULT; + CurTexture = NULL; + + pD3DDevice->SetTransform(D3DTS_VIEW, &matView); + pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); + + return true; +} diff --git a/archive/hgewin/hge_impl.h b/archive/hgewin/hge_impl.h new file mode 100755 index 0000000..244dafc --- /dev/null +++ b/archive/hgewin/hge_impl.h @@ -0,0 +1,356 @@ +// -*- C++ -*- +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Common core implementation header +** Upgraded to DirectX9 By Chris Xiong, 2013/08/08 +*/ + + +#ifndef HGE_IMPL_H +#define HGE_IMPL_H + +#include "hge.h" +#include <stdio.h> +#include <d3d9.h> +#include <d3dx9.h> + +#define DEMO + +#define D3DFVF_HGEVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) +#define VERTEX_BUFFER_SIZE 4000 + + +typedef BOOL (WINAPI *GetSystemPowerStatusFunc)(LPSYSTEM_POWER_STATUS); + + +struct CRenderTargetList +{ + int width; + int height; + IDirect3DTexture9* pTex; + IDirect3DSurface9* pDepth; + CRenderTargetList* next; +}; + +struct CTextureList +{ + HTEXTURE tex; + int width; + int height; + CTextureList* next; +}; + +struct CResourceList +{ + char filename[_MAX_PATH]; + char password[64]; + CResourceList* next; +}; + +struct CStreamList +{ + HSTREAM hstream; + void* data; + CStreamList* next; +}; + +struct CInputEventList +{ + hgeInputEvent event; + CInputEventList* next; +}; + + +void DInit(); +void DDone(); +bool DFrame(); + + +/* +** HGE Interface implementation +*/ +class HGE_Impl : public HGE +{ +public: + virtual void CALL Release(); + + virtual bool CALL System_Initiate(); + virtual void CALL System_Shutdown(); + virtual bool CALL System_Start(); + virtual void CALL System_SetStateBool (hgeBoolState state, bool value); + virtual void CALL System_SetStateFunc (hgeFuncState state, hgeCallback value); + virtual void CALL System_SetStateHwnd (hgeHwndState state, HWND value); + virtual void CALL System_SetStateInt (hgeIntState state, int value); + virtual void CALL System_SetStateString(hgeStringState state, const char *value); + virtual bool CALL System_GetStateBool (hgeBoolState ); + virtual hgeCallback CALL System_GetStateFunc (hgeFuncState ); + virtual HWND CALL System_GetStateHwnd (hgeHwndState ); + virtual int CALL System_GetStateInt (hgeIntState ); + virtual const char* CALL System_GetStateString(hgeStringState); + virtual const char* CALL System_GetErrorMessage(); + virtual void CALL System_Log(const char *format, ...); + virtual bool CALL System_Launch(const char *url); + virtual void CALL System_Snapshot(const char *filename=0); + + virtual void* CALL Resource_Load(const char *filename, DWORD *size=0); + virtual void CALL Resource_Free(void *res); + virtual bool CALL Resource_AttachPack(const char *filename, const char *password=0); + virtual void CALL Resource_RemovePack(const char *filename); + virtual void CALL Resource_RemoveAllPacks(); + virtual char* CALL Resource_MakePath(const char *filename=0); + virtual char* CALL Resource_EnumFiles(const char *wildcard=0); + virtual char* CALL Resource_EnumFolders(const char *wildcard=0); + + virtual void CALL Ini_SetInt(const char *section, const char *name, int value); + virtual int CALL Ini_GetInt(const char *section, const char *name, int def_val); + virtual void CALL Ini_SetFloat(const char *section, const char *name, float value); + virtual float CALL Ini_GetFloat(const char *section, const char *name, float def_val); + virtual void CALL Ini_SetString(const char *section, const char *name, const char *value); + virtual char* CALL Ini_GetString(const char *section, const char *name, const char *def_val); + + virtual void CALL Random_Seed(int seed=0); + virtual int CALL Random_Int(int min, int max); + virtual float CALL Random_Float(float min, float max); + + virtual float CALL Timer_GetTime(); + virtual float CALL Timer_GetDelta(); + virtual int CALL Timer_GetFPS(); + virtual float CALL Timer_GetFPSf(); + + virtual HEFFECT CALL Effect_Load(const char *filename, DWORD size=0); + virtual void CALL Effect_Free(HEFFECT eff); + virtual HCHANNEL CALL Effect_Play(HEFFECT eff); + virtual HCHANNEL CALL Effect_PlayEx(HEFFECT eff, float volume=1.0, float pan=0.0, float pitch=1.0f, bool loop=false); + + virtual HMUSIC CALL Music_Load(const char *filename, DWORD size=0); + virtual void CALL Music_Free(HMUSIC mus); + virtual HCHANNEL CALL Music_Play(HMUSIC mus, bool loop, int volume = 100, int order = 0, int row = 0); + virtual void CALL Music_SetAmplification(HMUSIC music, int ampl); + virtual int CALL Music_GetAmplification(HMUSIC music); + virtual int CALL Music_GetLength(HMUSIC music); + virtual void CALL Music_SetPos(HMUSIC music, int order, int row); + virtual bool CALL Music_GetPos(HMUSIC music, int *order, int *row); + virtual void CALL Music_SetInstrVolume(HMUSIC music, int instr, int volume); + virtual int CALL Music_GetInstrVolume(HMUSIC music, int instr); + virtual void CALL Music_SetChannelVolume(HMUSIC music, int channel, int volume); + virtual int CALL Music_GetChannelVolume(HMUSIC music, int channel); + + virtual HSTREAM CALL Stream_Load(const char *filename, DWORD size=0); + virtual void CALL Stream_Free(HSTREAM stream); + virtual HCHANNEL CALL Stream_Play(HSTREAM stream, bool loop, int volume = 100); + + virtual void CALL Channel_SetPanning(HCHANNEL chn, float pan); + virtual void CALL Channel_SetVolume(HCHANNEL chn, float volume); + virtual void CALL Channel_SetPitch(HCHANNEL chn, float pitch); + virtual void CALL Channel_Pause(HCHANNEL chn); + virtual void CALL Channel_Resume(HCHANNEL chn); + virtual void CALL Channel_Stop(HCHANNEL chn); + virtual void CALL Channel_PauseAll(); + virtual void CALL Channel_ResumeAll(); + virtual void CALL Channel_StopAll(); + virtual bool CALL Channel_IsPlaying(HCHANNEL chn);
+ virtual float CALL Channel_GetLength(HCHANNEL chn);
+ virtual float CALL Channel_GetPos(HCHANNEL chn);
+ virtual void CALL Channel_SetPos(HCHANNEL chn, float fSeconds);
+ virtual int CALL Channel_GetPos_BySample(HCHANNEL chn);
+ virtual void CALL Channel_SetPos_BySample(HCHANNEL chn, int iSample);
+ virtual void CALL Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan = -101, float pitch = -1);
+ virtual bool CALL Channel_IsSliding(HCHANNEL channel); + + virtual void CALL Input_GetMousePos(float *x, float *y); + virtual void CALL Input_SetMousePos(float x, float y); + virtual int CALL Input_GetMouseWheel(); + virtual bool CALL Input_IsMouseOver(); + virtual bool CALL Input_KeyDown(int key); + virtual bool CALL Input_KeyUp(int key); + virtual bool CALL Input_GetKeyState(int key); + virtual int CALL Input_GetKeyStateEx(int key); + virtual const char* CALL Input_GetKeyName(int key); + virtual int CALL Input_GetKey(); + virtual int CALL Input_GetChar(); + virtual bool CALL Input_GetEvent(hgeInputEvent *event); + + virtual bool CALL Gfx_BeginScene(HTARGET target=0); + virtual void CALL Gfx_EndScene(); + virtual void CALL Gfx_Clear(DWORD color); + virtual void CALL Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color=0xFFFFFFFF, float z=0.5f); + virtual void CALL Gfx_RenderTriple(const hgeTriple *triple); + virtual void CALL Gfx_RenderQuad(const hgeQuad *quad); + virtual hgeVertex* CALL Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim); + virtual void CALL Gfx_FinishBatch(int nprim); + virtual void CALL Gfx_SetClipping(int x=0, int y=0, int w=0, int h=0); + virtual void CALL Gfx_SetTransform(float x=0, float y=0, float dx=0, float dy=0, float rot=0, float hscale=0, float vscale=0); + + virtual HTARGET CALL Target_Create(int width, int height, bool zbuffer); + virtual void CALL Target_Free(HTARGET target); + virtual HTEXTURE CALL Target_GetTexture(HTARGET target); + + virtual HTEXTURE CALL Texture_Create(int width, int height); + virtual HTEXTURE CALL Texture_Load(const char *filename, DWORD size=0, bool bMipmap=false); + virtual void CALL Texture_Free(HTEXTURE tex); + virtual int CALL Texture_GetWidth(HTEXTURE tex, bool bOriginal=false); + virtual int CALL Texture_GetHeight(HTEXTURE tex, bool bOriginal=false); + virtual DWORD* CALL Texture_Lock(HTEXTURE tex, bool bReadOnly=true, int left=0, int top=0, int width=0, int height=0); + virtual void CALL Texture_Unlock(HTEXTURE tex); + + //////// Implementation //////// + + static HGE_Impl* _Interface_Get(); + void _FocusChange(bool bAct); + void _PostError(const char *error); + + + HINSTANCE hInstance; + HWND hwnd; + + bool bActive; + char szError[256]; + char szAppPath[_MAX_PATH]; + char szIniString[256]; + + + // System States + bool (*procFrameFunc)(); + bool (*procRenderFunc)(); + bool (*procFocusLostFunc)(); + bool (*procFocusGainFunc)(); + bool (*procGfxRestoreFunc)(); + bool (*procExitFunc)(); + const char* szIcon; + char szWinTitle[256]; + int nScreenWidth; + int nScreenHeight; + int nScreenBPP; + bool bWindowed; + bool bZBuffer; + bool bTextureFilter; + char szIniFile[_MAX_PATH]; + char szLogFile[_MAX_PATH]; + bool bUseSound; + int nSampleRate; + int nFXVolume; + int nMusVolume; + int nStreamVolume; + int nHGEFPS; + bool bHideMouse; + bool bDontSuspend; + HWND hwndParent; + + #ifdef DEMO + bool bDMO; + #endif + + + // Power + int nPowerStatus; + HMODULE hKrnl32; + GetSystemPowerStatusFunc lpfnGetSystemPowerStatus; + + void _InitPowerStatus(); + void _UpdatePowerStatus(); + void _DonePowerStatus(); + + + // Graphics + D3DPRESENT_PARAMETERS* d3dpp; + + D3DPRESENT_PARAMETERS d3dppW; + RECT rectW; + LONG styleW; + + D3DPRESENT_PARAMETERS d3dppFS; + RECT rectFS; + LONG styleFS; + + IDirect3D9* pD3D; + IDirect3DDevice9* pD3DDevice; + IDirect3DVertexBuffer9* pVB; + IDirect3DIndexBuffer9* pIB; + + IDirect3DSurface9* pScreenSurf; + IDirect3DSurface9* pScreenDepth; + CRenderTargetList* pTargets; + CRenderTargetList* pCurTarget; + + D3DXMATRIX matView; + D3DXMATRIX matProj; + + CTextureList* textures; + hgeVertex* VertArray; + + int nPrim; + int CurPrimType; + int CurBlendMode; + HTEXTURE CurTexture; + + bool _GfxInit(); + void _GfxDone(); + bool _GfxRestore(); + void _AdjustWindow(); + void _Resize(int width, int height); + bool _init_lost(); + void _render_batch(bool bEndScene=false); + int _format_id(D3DFORMAT fmt); + void _SetBlendMode(int blend); + void _SetProjectionMatrix(int width, int height); + + + // Audio + //HINSTANCE hBass; + void* hOpenAL; + bool bSilent; + CStreamList* streams; + bool _SoundInit(); + void _SoundDone(); + void _SetMusVolume(int vol); + void _SetStreamVolume(int vol); + void _SetFXVolume(int vol); + + + // Input + int VKey; + int Char; + int Zpos; + float Xpos; + float Ypos; + bool bMouseOver; + bool bCaptured; + char keyz[256]; + bool keylast[256]; + CInputEventList* queue; + void _UpdateMouse(); + void _InputInit(); + void _ClearQueue(); + void _BuildEvent(int type, int key, int scan, int flags, int x, int y); + + + // Resources + char szTmpFilename[_MAX_PATH]; + CResourceList* res; + HANDLE hSearch; + WIN32_FIND_DATA SearchData; + + + // Timer + float fTime; + float fDeltaTime; + float fUpdateFPSDelay; + float nFPSf; + DWORD nFixedDelta; + int nFPS; + int Fcnt; + DWORD t0, t0fps, dt; + int cfps; + + +private: + HGE_Impl(); +}; + +extern HGE_Impl* pHGE; + +#endif + diff --git a/archive/hgewin/ini.cpp b/archive/hgewin/ini.cpp new file mode 100755 index 0000000..eef4354 --- /dev/null +++ b/archive/hgewin/ini.cpp @@ -0,0 +1,73 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: ini file +*/ + + +#include "hge_impl.h" + + +void CALL HGE_Impl::Ini_SetInt(const char *section, const char *name, int value) +{ + char buf[256]; + + if(szIniFile[0]) { + sprintf(buf,"%d",value); + WritePrivateProfileString(section, name, buf, szIniFile); + } +} + + +int CALL HGE_Impl::Ini_GetInt(const char *section, const char *name, int def_val) +{ + char buf[256]; + + if(szIniFile[0]) { + if(GetPrivateProfileString(section, name, "", buf, sizeof(buf), szIniFile)) + { return atoi(buf); } + else { return def_val; } + } + return def_val; +} + + +void CALL HGE_Impl::Ini_SetFloat(const char *section, const char *name, float value) +{ + char buf[256]; + + if(szIniFile[0]) { + sprintf(buf,"%f",value); + WritePrivateProfileString(section, name, buf, szIniFile); + } +} + + +float CALL HGE_Impl::Ini_GetFloat(const char *section, const char *name, float def_val) +{ + char buf[256]; + + if(szIniFile[0]) { + if(GetPrivateProfileString(section, name, "", buf, sizeof(buf), szIniFile)) + { return (float)atof(buf); } + else { return def_val; } + } + return def_val; +} + + +void CALL HGE_Impl::Ini_SetString(const char *section, const char *name, const char *value) +{ + if(szIniFile[0]) WritePrivateProfileString(section, name, value, szIniFile); +} + + +char* CALL HGE_Impl::Ini_GetString(const char *section, const char *name, const char *def_val) +{ + if(szIniFile[0]) GetPrivateProfileString(section, name, def_val, szIniString, sizeof(szIniString), szIniFile); + else strcpy(szIniString, def_val); + return szIniString; +} + diff --git a/archive/hgewin/input.cpp b/archive/hgewin/input.cpp new file mode 100755 index 0000000..0610376 --- /dev/null +++ b/archive/hgewin/input.cpp @@ -0,0 +1,261 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: input +*/ + + +#include "hge_impl.h" + + +const char *KeyNames[] = +{ + "?", + "Left Mouse Button", "Right Mouse Button", "?", "Middle Mouse Button", + "?", "?", "?", "Backspace", "Tab", "?", "?", "?", "Enter", "?", "?", + "Shift", "Ctrl", "Alt", "Pause", "Caps Lock", "?", "?", "?", "?", "?", "?", + "Escape", "?", "?", "?", "?", + "Space", "Page Up", "Page Down", "End", "Home", + "Left Arrow", "Up Arrow", "Right Arrow", "Down Arrow", + "?", "?", "?", "?", "Insert", "Delete", "?", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "?", "?", "?", "?", "?", "?", "?", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "Left Win", "Right Win", "Application", "?", "?", + "NumPad 0", "NumPad 1", "NumPad 2", "NumPad 3", "NumPad 4", + "NumPad 5", "NumPad 6", "NumPad 7", "NumPad 8", "NumPad 9", + "Multiply", "Add", "?", "Subtract", "Decimal", "Divide", + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "Num Lock", "Scroll Lock", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "Semicolon", "Equals", "Comma", "Minus", "Period", "Slash", "Grave", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", + "Left bracket", "Backslash", "Right bracket", "Apostrophe", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", + "?", "?", "?" +}; + + +bool CALL HGE_Impl::Input_GetEvent(hgeInputEvent *event) +{ + CInputEventList *eptr; + + if(queue) + { + eptr=queue; + memcpy(event, &eptr->event, sizeof(hgeInputEvent)); + queue=eptr->next; + delete eptr; + return true; + } + + return false; +} + +void CALL HGE_Impl::Input_GetMousePos(float *x, float *y) +{ + *x=Xpos; *y=Ypos; +} + + +void CALL HGE_Impl::Input_SetMousePos(float x, float y) +{ + POINT pt; + pt.x=(long)x; pt.y=(long)y; + ClientToScreen(hwnd, &pt); + SetCursorPos(pt.x,pt.y); +} + +int CALL HGE_Impl::Input_GetMouseWheel() +{ + return Zpos; +} + +bool CALL HGE_Impl::Input_IsMouseOver() +{ + return bMouseOver; +} + +bool CALL HGE_Impl::Input_GetKeyState(int key) +{ + return ((GetKeyState(key) & 0x8000) != 0); +} + +int CALL HGE_Impl::Input_GetKeyStateEx(int key)//New function +{ + if (!Input_GetKeyState(key)&&keylast[key])return HGEKST_RELEASE; + if (!Input_GetKeyState(key))return HGEKST_NONE; + if (keylast[key])return HGEKST_KEEP; + return HGEKST_HIT; +} + +bool CALL HGE_Impl::Input_KeyDown(int key) +{ + return (keyz[key] & 1) != 0; +} + +bool CALL HGE_Impl::Input_KeyUp(int key) +{ + return (keyz[key] & 2) != 0; +} + +const char* CALL HGE_Impl::Input_GetKeyName(int key) +{ + return KeyNames[key]; +} + +int CALL HGE_Impl::Input_GetKey() +{ + return VKey; +} + +int CALL HGE_Impl::Input_GetChar() +{ + return Char; +} + + +//////// Implementation //////// + + +void HGE_Impl::_InputInit() +{ + POINT pt; + GetCursorPos(&pt); + ScreenToClient(hwnd, &pt); + Xpos = (float)pt.x; + Ypos = (float)pt.y; + + memset(&keyz, 0, sizeof(keyz)); + memset(keylast,0,sizeof(keylast)); +} + +void HGE_Impl::_UpdateMouse() +{ + POINT pt; + RECT rc; + + GetCursorPos(&pt); + GetClientRect(hwnd, &rc); + MapWindowPoints(hwnd, NULL, (LPPOINT)&rc, 2); + + if(bCaptured || (PtInRect(&rc, pt) && WindowFromPoint(pt)==hwnd)) + bMouseOver=true; + else + bMouseOver=false; +} + +void HGE_Impl::_BuildEvent(int type, int key, int scan, int flags, int x, int y) +{ + CInputEventList *last, *eptr=new CInputEventList; + unsigned char kbstate[256]; + POINT pt; + + eptr->event.type=type; + eptr->event.chr=0; + pt.x=x; pt.y=y; + + GetKeyboardState(kbstate); + if(type==INPUT_KEYDOWN) + { + if((flags & HGEINP_REPEAT) == 0) keyz[key] |= 1; + ToAscii(key, scan, kbstate, (unsigned short *)&eptr->event.chr, 0); + } + if(type==INPUT_KEYUP) + { + keyz[key] |= 2; + ToAscii(key, scan, kbstate, (unsigned short *)&eptr->event.chr, 0); + } + if(type==INPUT_MOUSEWHEEL) + { + eptr->event.key=0; eptr->event.wheel=key; + ScreenToClient(hwnd,&pt); + } + else { eptr->event.key=key; eptr->event.wheel=0; } + + if(type==INPUT_MBUTTONDOWN) + { + keyz[key] |= 1; + SetCapture(hwnd); + bCaptured=true; + } + if(type==INPUT_MBUTTONUP) + { + keyz[key] |= 2; + ReleaseCapture(); + Input_SetMousePos(Xpos, Ypos); + pt.x=(int)Xpos; pt.y=(int)Ypos; + bCaptured=false; + } + + if(kbstate[VK_SHIFT] & 0x80) flags|=HGEINP_SHIFT; + if(kbstate[VK_CONTROL] & 0x80) flags|=HGEINP_CTRL; + if(kbstate[VK_MENU] & 0x80) flags|=HGEINP_ALT; + if(kbstate[VK_CAPITAL] & 0x1) flags|=HGEINP_CAPSLOCK; + if(kbstate[VK_SCROLL] & 0x1) flags|=HGEINP_SCROLLLOCK; + if(kbstate[VK_NUMLOCK] & 0x1) flags|=HGEINP_NUMLOCK; + eptr->event.flags=flags; + + if(pt.x==-1) { eptr->event.x=Xpos;eptr->event.y=Ypos; } + else + { + if(pt.x<0) pt.x=0; + if(pt.y<0) pt.y=0; + if(pt.x>=nScreenWidth) pt.x=nScreenWidth-1; + if(pt.y>=nScreenHeight) pt.y=nScreenHeight-1; + + eptr->event.x=(float)pt.x; + eptr->event.y=(float)pt.y; + } + + eptr->next=0; + + if(!queue) queue=eptr; + else + { + last=queue; + while(last->next) last=last->next; + last->next=eptr; + } + + if(eptr->event.type==INPUT_KEYDOWN || eptr->event.type==INPUT_MBUTTONDOWN) + { + VKey=eptr->event.key;Char=eptr->event.chr; + } + else if(eptr->event.type==INPUT_MOUSEMOVE) + { + Xpos=eptr->event.x;Ypos=eptr->event.y; + } + else if(eptr->event.type==INPUT_MOUSEWHEEL) + { + Zpos+=eptr->event.wheel; + } +} + +void HGE_Impl::_ClearQueue() +{ + CInputEventList *nexteptr, *eptr=queue; + + memset(&keyz, 0, sizeof(keyz)); + + while(eptr) + { + nexteptr=eptr->next; + delete eptr; + eptr=nexteptr; + } + + queue=0; VKey=0; Char=0; Zpos=0; +} diff --git a/archive/hgewin/power.cpp b/archive/hgewin/power.cpp new file mode 100755 index 0000000..dadcda9 --- /dev/null +++ b/archive/hgewin/power.cpp @@ -0,0 +1,53 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: power status +*/ + + +#include "hge_impl.h" + + +void HGE_Impl::_InitPowerStatus() +{ + hKrnl32 = LoadLibrary("kernel32.dll"); + + if(hKrnl32 != NULL) + lpfnGetSystemPowerStatus = (GetSystemPowerStatusFunc)GetProcAddress(hKrnl32, "GetSystemPowerStatus"); + + _UpdatePowerStatus(); +} + + +void HGE_Impl::_UpdatePowerStatus() +{ + SYSTEM_POWER_STATUS ps; + + if(lpfnGetSystemPowerStatus != NULL && lpfnGetSystemPowerStatus(&ps)) + { + if(ps.ACLineStatus == 1) + { + nPowerStatus = HGEPWR_AC; + } + else if(ps.BatteryFlag < 128) + { + nPowerStatus = ps.BatteryLifePercent; + } + else + { + nPowerStatus = HGEPWR_UNSUPPORTED; + } + } + else + { + nPowerStatus = HGEPWR_UNSUPPORTED; + } +} + + +void HGE_Impl::_DonePowerStatus() +{ + if(hKrnl32 != NULL) FreeLibrary(hKrnl32); +} diff --git a/archive/hgewin/random.cpp b/archive/hgewin/random.cpp new file mode 100755 index 0000000..c3332f1 --- /dev/null +++ b/archive/hgewin/random.cpp @@ -0,0 +1,32 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: random number generation +*/ + + +#include "hge_impl.h" + + +unsigned int g_seed=0; + +void CALL HGE_Impl::Random_Seed(int seed) +{ + if(!seed) g_seed=timeGetTime(); + else g_seed=seed; +} + +int CALL HGE_Impl::Random_Int(int min, int max) +{ + g_seed=214013*g_seed+2531011; + return min+(g_seed ^ g_seed>>15)%(max-min+1); +} + +float CALL HGE_Impl::Random_Float(float min, float max) +{ + g_seed=214013*g_seed+2531011; + //return min+g_seed*(1.0f/4294967295.0f)*(max-min); + return min+(g_seed>>16)*(1.0f/65535.0f)*(max-min); +} diff --git a/archive/hgewin/resource.cpp b/archive/hgewin/resource.cpp new file mode 100755 index 0000000..6921dc6 --- /dev/null +++ b/archive/hgewin/resource.cpp @@ -0,0 +1,259 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: resources management +*/ + + +#include "hge_impl.h" + +#define NOCRYPT +//#define NOUNCRYPT +#include "ZLIB/unzip.h" + + +bool CALL HGE_Impl::Resource_AttachPack(const char *filename, const char *password) +{ + char *szName; + CResourceList *resItem=res; + unzFile zip; + + szName=Resource_MakePath(filename); + strupr(szName); + + while(resItem) + { + if(!strcmp(szName,resItem->filename)) return false; + resItem=resItem->next; + } + + zip=unzOpen(szName); + if(!zip) return false; + unzClose(zip); + + resItem=new CResourceList; + strcpy(resItem->filename, szName); + if(password) strcpy(resItem->password, password); + else resItem->password[0]=0; + resItem->next=res; + res=resItem; + + return true; +} + +void CALL HGE_Impl::Resource_RemovePack(const char *filename) +{ + char *szName; + CResourceList *resItem=res, *resPrev=0; + + szName=Resource_MakePath(filename); + strupr(szName); + + while(resItem) + { + if(!strcmp(szName,resItem->filename)) + { + if(resPrev) resPrev->next=resItem->next; + else res=resItem->next; + delete resItem; + break; + } + + resPrev=resItem; + resItem=resItem->next; + } +} + +void CALL HGE_Impl::Resource_RemoveAllPacks() +{ + CResourceList *resItem=res, *resNextItem; + + while(resItem) + { + resNextItem=resItem->next; + delete resItem; + resItem=resNextItem; + } + + res=0; +} +#undef DWORD +void* CALL HGE_Impl::Resource_Load(const char *filename, DWORD *size) +{ + static const char *res_err="Can't load resource: %s"; + + CResourceList *resItem=res; + char szName[_MAX_PATH]; + char szZipName[_MAX_PATH]; + unzFile zip; + unz_file_info file_info; + int done, i; + void *ptr; + HANDLE hF; + + if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') goto _fromfile; // skip absolute paths + + // Load from pack + + strcpy(szName,filename); + strupr(szName); + for(i=0; szName[i]; i++) { if(szName[i]=='/') szName[i]='\\'; } + + while(resItem) + { + zip=unzOpen(resItem->filename); + done=unzGoToFirstFile(zip); + while(done==UNZ_OK) + { + unzGetCurrentFileInfo(zip, &file_info, szZipName, sizeof(szZipName), NULL, 0, NULL, 0); + strupr(szZipName); + for(i=0; szZipName[i]; i++) { if(szZipName[i]=='/') szZipName[i]='\\'; } + if(!strcmp(szName,szZipName)) + { + if(unzOpenCurrentFilePassword(zip, resItem->password[0] ? resItem->password : 0) != UNZ_OK) + { + unzClose(zip); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + ptr = malloc(file_info.uncompressed_size); + if(!ptr) + { + unzCloseCurrentFile(zip); + unzClose(zip); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + if(unzReadCurrentFile(zip, ptr, file_info.uncompressed_size) < 0) + { + unzCloseCurrentFile(zip); + unzClose(zip); + free(ptr); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + unzCloseCurrentFile(zip); + unzClose(zip); + if(size) *size=file_info.uncompressed_size; + return ptr; + } + + done=unzGoToNextFile(zip); + } + + unzClose(zip); + resItem=resItem->next; + } + + // Load from file +_fromfile: + + hF = CreateFile(Resource_MakePath(filename), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + if(hF == INVALID_HANDLE_VALUE) + { + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + file_info.uncompressed_size = GetFileSize(hF, NULL); + ptr = malloc(file_info.uncompressed_size); + if(!ptr) + { + CloseHandle(hF); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + if(ReadFile(hF, ptr, file_info.uncompressed_size, (LPDWORD)&file_info.uncompressed_size, NULL ) == 0) + { + CloseHandle(hF); + free(ptr); + sprintf(szName, res_err, filename); + _PostError(szName); + return 0; + } + + CloseHandle(hF); + if(size) *size=file_info.uncompressed_size; + return ptr; +} + + +void CALL HGE_Impl::Resource_Free(void *res) +{ + if(res) free(res); +} + + +char* CALL HGE_Impl::Resource_MakePath(const char *filename) +{ + int i; + + if(!filename) + strcpy(szTmpFilename, szAppPath); + else if(filename[0]=='\\' || filename[0]=='/' || filename[1]==':') + strcpy(szTmpFilename, filename); + else + { + strcpy(szTmpFilename, szAppPath); + if(filename) strcat(szTmpFilename, filename); + } + + for(i=0; szTmpFilename[i]; i++) { if(szTmpFilename[i]=='/') szTmpFilename[i]='\\'; } + return szTmpFilename; +} + +char* CALL HGE_Impl::Resource_EnumFiles(const char *wildcard) +{ + if(wildcard) + { + if(hSearch) { FindClose(hSearch); hSearch=0; } + hSearch=FindFirstFile(Resource_MakePath(wildcard), &SearchData); + if(hSearch==INVALID_HANDLE_VALUE) { hSearch=0; return 0; } + + if(!(SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) return SearchData.cFileName; + else return Resource_EnumFiles(); + } + else + { + if(!hSearch) return 0; + for(;;) + { + if(!FindNextFile(hSearch, &SearchData)) { FindClose(hSearch); hSearch=0; return 0; } + if(!(SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) return SearchData.cFileName; + } + } +} + +char* CALL HGE_Impl::Resource_EnumFolders(const char *wildcard) +{ + if(wildcard) + { + if(hSearch) { FindClose(hSearch); hSearch=0; } + hSearch=FindFirstFile(Resource_MakePath(wildcard), &SearchData); + if(hSearch==INVALID_HANDLE_VALUE) { hSearch=0; return 0; } + + if((SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + strcmp(SearchData.cFileName,".") && strcmp(SearchData.cFileName,"..")) + return SearchData.cFileName; + else return Resource_EnumFolders(); + } + else + { + if(!hSearch) return 0; + for(;;) + { + if(!FindNextFile(hSearch, &SearchData)) { FindClose(hSearch); hSearch=0; return 0; } + if((SearchData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + strcmp(SearchData.cFileName,".") && strcmp(SearchData.cFileName,"..")) + return SearchData.cFileName; + } + } +} diff --git a/archive/hgewin/sound.cpp b/archive/hgewin/sound.cpp new file mode 100644 index 0000000..9024652 --- /dev/null +++ b/archive/hgewin/sound.cpp @@ -0,0 +1,531 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: audio routines +*/ + + +// This is just enough to get Hammerfight working without using libBA$$. +// If you want a full HGE audio implementation, you should either use the +// code in sound_libbass.cpp (and maybe pay for a BA$$ licen$e), or improve +// this code. +// Well, this code is now improved by Chris Xiong, adding several new interfaces. +// (Such as seeking in sample...) +// Channel functions are fully supported now. However music and streaming are +// still not supported. Some APIs changed for OpenAL is different from BA$$. + +#include "hge_impl.h" + +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/alext.h" +#include "ogg/ogg.h" +#include "vorbis/vorbisfile.h" +static const char* SOUND_SRC_FN="hge/sound.cpp"; +struct oggcbdata +{ + const BYTE *data; + DWORD size; + DWORD pos; +}; + +static size_t oggcb_read(void *ptr, size_t size, size_t nmemb, void *datasource) +{ + oggcbdata *data = (oggcbdata *) datasource; + const DWORD avail = data->size - data->pos; + size_t want = nmemb * size; + if (want > avail) + want = avail - (avail % size); + if (want > 0) + { + memcpy(ptr, data->data + data->pos, want); + data->pos += want; + } + return want / size; +} + +static int oggcb_seek(void *datasource, ogg_int64_t offset, int whence) +{ + oggcbdata *data = (oggcbdata *) datasource; + ogg_int64_t pos = 0; + switch (whence) + { + case SEEK_SET: pos = offset; break; + case SEEK_CUR: pos = ((ogg_int64_t) data->pos) + offset; break; + case SEEK_END: pos = ((ogg_int64_t) data->size) + offset; break; + default: return -1; + } + + if ( (pos < 0) || (pos > ((ogg_int64_t) data->size)) ) + return -1; + + data->pos = (DWORD) pos; + return 0; +} + +static int oggcb_close(void *datasource) +{ + return 0; +} + +static long oggcb_tell(void *datasource) +{ + oggcbdata *data = (oggcbdata *) datasource; + return (long) data->pos; +} + +static ov_callbacks oggcb = { oggcb_read, oggcb_seek, oggcb_close, oggcb_tell }; + +static void *decompress_vorbis(const BYTE *data, const DWORD size, ALsizei *decompressed_size, ALenum *fmt, ALsizei *freq) +{ +#ifdef __POWERPC__ + const int bigendian = 1; +#else + const int bigendian = 0; +#endif + + oggcbdata cbdata = { data, size, 0 }; + OggVorbis_File vf; + memset(&vf, '\0', sizeof (vf)); + if (ov_open_callbacks(&cbdata, &vf, NULL, 0, oggcb) == 0) + { + int bitstream = 0; + vorbis_info *info = ov_info(&vf, -1); + + *decompressed_size = 0; + *fmt = (info->channels == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + *freq = info->rate; + + if ((info->channels != 1) && (info->channels != 2)) + { + ov_clear(&vf); + return NULL; + } + + char buf[1024 * 16]; + long rc = 0; + size_t allocated = 64 * 1024; + BYTE *retval = (ALubyte *) malloc(allocated); + while ( (rc = ov_read(&vf, buf, sizeof (buf), bigendian, 2, 1, &bitstream)) != 0 ) + { + if (rc > 0) + { + *decompressed_size += rc; + if ((unsigned)*decompressed_size >= allocated) + { + allocated *= 2; + ALubyte *tmp = (ALubyte *) realloc(retval, allocated); + if (tmp == NULL) + { + free(retval); + retval = NULL; + break; + } + retval = tmp; + } + memcpy(retval + (*decompressed_size - rc), buf, rc); + } + } + ov_clear(&vf); + return retval; + } + + return NULL; +} + +#define MAX_SIDS 128 +static int sidcount = 0; +static ALuint sids[MAX_SIDS]; + +static ALuint get_source() +{ + for (int i = 0; i < sidcount; i++) + { + ALint state = AL_PLAYING; + alGetSourceiv(sids[i], AL_SOURCE_STATE, &state); + if ((state != AL_PLAYING) && (state != AL_PAUSED)) + return sids[i]; + } + if (sidcount >= MAX_SIDS) + return 0; + + ALuint sid = 0; + alGenSources(1, &sid); + if (sid == 0) + return 0; + sids[sidcount++] = sid; + return sid; +} + + +HEFFECT CALL HGE_Impl::Effect_Load(const char *filename, DWORD size) +{ + DWORD _size; + void *data; + + if(hOpenAL) + { + if(bSilent) return 1; + + if(size) { data=(void *)filename; _size=size; } + else + { + data=Resource_Load(filename, &_size); + if(!data) return 0; + } + + const BYTE *magic = (const BYTE *) data; + const bool isOgg = ( (_size > 4) && + (magic[0] == 'O') && (magic[1] == 'g') && + (magic[2] == 'g') && (magic[3] == 'S') ); + if (!isOgg) + { + if(!size) Resource_Free(data); + return 0; + } + void *allocation_decompressed = NULL; + void *decompressed = NULL; + ALsizei decompressed_size = 0; + ALsizei freq = 0; + ALenum fmt = AL_FORMAT_STEREO16; + if (isOgg) + { + /*if (alIsExtensionPresent((const ALchar *) "AL_EXT_vorbis"))//useless + { + fmt = alGetEnumValue((const ALchar *) "AL_FORMAT_VORBIS_EXT"); + decompressed = data; + decompressed_size = _size; + } + else + {*/ + allocation_decompressed = decompress_vorbis((const BYTE *) data, _size, &decompressed_size, &fmt, &freq); + decompressed = allocation_decompressed; + //} + } + + ALuint bid = 0; + alGenBuffers(1, &bid); + alBufferData(bid, fmt, decompressed, decompressed_size, freq); + free(allocation_decompressed); // not delete[] ! + if(!size) Resource_Free(data); + return (HEFFECT) bid; + } + else return 0; +} + +HCHANNEL CALL HGE_Impl::Effect_Play(HEFFECT eff) +{ + return Effect_PlayEx(eff, 1.0f, 0, 1.0f, false); +} + +HCHANNEL CALL HGE_Impl::Effect_PlayEx(HEFFECT eff, float volume, float pan, float pitch, bool loop) +{ + if(hOpenAL) + { + const ALuint sid = get_source(); // find an unused sid, or generate a new one. + if (sid != 0) + { + if (volume < 0) volume = 0; else if (volume > 1.0) volume = 1.0; + if (pan < -1.0) pan = -1.0; else if (pan > 1.0) pan = 1.0; + alSourceStop(sid); + alSourcei(sid, AL_BUFFER, (ALint) eff); + alSourcef(sid, AL_GAIN, volume); + alSourcef(sid, AL_PITCH, pitch); + alSource3f(sid, AL_POSITION, pan, 0.0f, 0.0f); + alSourcei(sid, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); + alSourcePlay(sid); + } + return sid; + } + else return 0; +} + +void CALL HGE_Impl::Effect_Free(HEFFECT eff) +{ + if(hOpenAL) + { + ALuint bid = (ALuint) eff; + alDeleteBuffers(1, &bid); + } +} +//Castrate!! +HMUSIC CALL HGE_Impl::Music_Load(const char *filename, DWORD size){return 0;} + +HCHANNEL CALL HGE_Impl::Music_Play(HMUSIC mus, bool loop, int volume, int order, int row){return 0;} + +void CALL HGE_Impl::Music_Free(HMUSIC mus){} + +void CALL HGE_Impl::Music_SetAmplification(HMUSIC music, int ampl){} + +int CALL HGE_Impl::Music_GetAmplification(HMUSIC music){return -1;} + +int CALL HGE_Impl::Music_GetLength(HMUSIC music){return -1;} + +void CALL HGE_Impl::Music_SetPos(HMUSIC music, int order, int row){} + +bool CALL HGE_Impl::Music_GetPos(HMUSIC music, int *order, int *row){return false;} + +void CALL HGE_Impl::Music_SetInstrVolume(HMUSIC music, int instr, int volume){} + +int CALL HGE_Impl::Music_GetInstrVolume(HMUSIC music, int instr){return -1;} + +void CALL HGE_Impl::Music_SetChannelVolume(HMUSIC music, int channel, int volume){} + +int CALL HGE_Impl::Music_GetChannelVolume(HMUSIC music, int channel){return -1;} + +HSTREAM CALL HGE_Impl::Stream_Load(const char *filename, DWORD size){return 0;} + +void CALL HGE_Impl::Stream_Free(HSTREAM stream){} + +HCHANNEL CALL HGE_Impl::Stream_Play(HSTREAM stream, bool loop, int volume){return 0;} + +void CALL HGE_Impl::Channel_SetPanning(HCHANNEL chn, float pan) +{ + if(pan>1.0)pan=1.0; + if(pan<-1.0)pan=-1.0; + if(hOpenAL) + { + alSource3f((ALuint) chn, AL_POSITION, pan, 0.0f, 0.0f); + } +} + +void CALL HGE_Impl::Channel_SetVolume(HCHANNEL chn, float volume) +{ + if(hOpenAL) + { + if (volume < 0) volume = 0; else if (volume > 1.0f) volume = 1.0f; + alSourcef((ALuint) chn, AL_GAIN, volume); + } +} + +void CALL HGE_Impl::Channel_SetPitch(HCHANNEL chn, float pitch) +{ + if(hOpenAL) + { + alSourcef((ALuint) chn, AL_PITCH, pitch); + } +} + +void CALL HGE_Impl::Channel_Pause(HCHANNEL chn) +{ + if(hOpenAL) + { + alSourcePause((ALuint) chn); + } +} + +void CALL HGE_Impl::Channel_Resume(HCHANNEL chn) +{ + if(hOpenAL) + { + alSourcePlay((ALuint) chn); + } +} + +void CALL HGE_Impl::Channel_Stop(HCHANNEL chn) +{ + if(hOpenAL) + { + alSourceStop((ALuint) chn); + } +} + +void CALL HGE_Impl::Channel_PauseAll() +{ + if(hOpenAL) + { + ALCcontext *ctx = alcGetCurrentContext(); + alcSuspendContext(ctx); + } +} + +void CALL HGE_Impl::Channel_ResumeAll() +{ + if(hOpenAL) + { + ALCcontext *ctx = alcGetCurrentContext(); + alcProcessContext(ctx); + } +} + +void CALL HGE_Impl::Channel_StopAll() +{ + if(hOpenAL) + { + for (int i = 0; i < sidcount; i++) + alSourceStop(sids[i]); + } +} + +bool CALL HGE_Impl::Channel_IsPlaying(HCHANNEL chn) +{ + if(hOpenAL) + { + ALint state = AL_STOPPED; + alGetSourceiv((ALuint) chn, AL_SOURCE_STATE, &state); + return state == AL_PLAYING; + } + else return false; +} +//The following features are ported to OpenAL by Chris +float CALL HGE_Impl::Channel_GetLength(HCHANNEL chn) +//WARNING!!:In OpenAL We pass HEFFECT insteat HCHANNEL in! +//This should be fixed. +{ + //Well, you developers should know this "by heart". + if (hOpenAL) + { + ALint sizeInBytes; + ALint channels; + ALint bits; + ALuint bufferID=chn; + alGetBufferi(bufferID, AL_SIZE, &sizeInBytes); + alGetBufferi(bufferID, AL_CHANNELS, &channels); + alGetBufferi(bufferID, AL_BITS, &bits); + int lengthInSamples = sizeInBytes * 8 / (channels * bits); + ALint frequency; + alGetBufferi(bufferID, AL_FREQUENCY, &frequency); + float durationInSeconds = (float)lengthInSamples / (float)frequency; + return durationInSeconds; + } + return -1; +} + +float CALL HGE_Impl::Channel_GetPos(HCHANNEL chn) +{ + if (hOpenAL) + { + ALfloat res; + alGetSourcef((ALuint)chn,AL_SEC_OFFSET,&res); + return (float)res; + } + else return -1.0f; +} + +void CALL HGE_Impl::Channel_SetPos(HCHANNEL chn, float fSeconds) +{ + if (hOpenAL) + { + alSourcef((ALuint)chn,AL_SEC_OFFSET,(ALfloat)fSeconds); + } +} + +int CALL HGE_Impl::Channel_GetPos_BySample(HCHANNEL chn) +{ + if (hOpenAL) + { + ALint res; + alGetSourcei((ALuint)chn,AL_SAMPLE_OFFSET,&res); + return (int)res; + } + else return -1; +} + +void CALL HGE_Impl::Channel_SetPos_BySample(HCHANNEL chn, int iSample) +{ + if (hOpenAL) + { + alSourcei((ALuint)chn,AL_SAMPLE_OFFSET,(ALint)iSample); + } +} + +void CALL HGE_Impl::Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan, float pitch){} + +bool CALL HGE_Impl::Channel_IsSliding(HCHANNEL channel){return false;} + + +//////// Implementation //////// + + +bool HGE_Impl::_SoundInit() +{ + if(!bUseSound || hOpenAL) return true; + + bSilent=false; + + sidcount = 0; + memset(sids, '\0', sizeof (sids)); + + System_Log("%s: Starting OpenAL init",SOUND_SRC_FN); + + ALCdevice *dev = alcOpenDevice(NULL); + if (!dev) + { + System_Log("%s: alcOpenDevice(NULL) failed, using no sound",SOUND_SRC_FN); + bSilent=true; + return true; + } + + ALint caps[] = { ALC_FREQUENCY, nSampleRate, 0 }; + ALCcontext *ctx = alcCreateContext(dev, caps); + if (!ctx) + { + alcCloseDevice(dev); + System_Log("%s: alcCreateContext(NULL) failed, using no sound",SOUND_SRC_FN); + bSilent=true; + return true; + } + + alcMakeContextCurrent(ctx); + alcProcessContext(ctx); + + System_Log("%s: OpenAL initialized successfully.",SOUND_SRC_FN); + System_Log("%s: AL_VENDOR: %s",SOUND_SRC_FN, (char *) alGetString(AL_VENDOR)); + System_Log("%s: AL_RENDERER: %s",SOUND_SRC_FN, (char *) alGetString(AL_RENDERER)); + System_Log("%s: AL_VERSION: %s",SOUND_SRC_FN,(char *) alGetString(AL_VERSION)); + System_Log("%s: AL_EXTENSIONS: %s",SOUND_SRC_FN,(char *) alGetString(AL_EXTENSIONS)); + + hOpenAL = (void *) 0x1; // something non-NULL (!!! FIXME: this should eventually be a library handle). + + _SetFXVolume(nFXVolume); + //_SetMusVolume(nMusVolume); + //_SetStreamVolume(nStreamVolume); + + return true; +} + +void HGE_Impl::_SoundDone() +{ + CStreamList *stmItem=streams, *stmNext; + + if(hOpenAL) + { + for (int i = 0; i < sidcount; i++) + alSourceStop(sids[i]); + alDeleteSources(sidcount, sids); + sidcount = 0; + memset(sids, '\0', sizeof (sids)); + + ALCcontext *ctx = alcGetCurrentContext(); + ALCdevice *dev = alcGetContextsDevice(ctx); + alcMakeContextCurrent(NULL); + alcSuspendContext(ctx); + alcDestroyContext(ctx); + alcCloseDevice(dev); + + hOpenAL=0; + + while(stmItem) + { + stmNext=stmItem->next; + Resource_Free(stmItem->data); + delete stmItem; + stmItem=stmNext; + } + streams=0; + } +} + +void HGE_Impl::_SetMusVolume(int vol){} + +void HGE_Impl::_SetStreamVolume(int vol){} + +void HGE_Impl::_SetFXVolume(int vol) +{ + if(hOpenAL) + { + alListenerf(AL_GAIN, ((ALfloat) vol) / 100.0f); + } +} diff --git a/archive/hgewin/system.cpp b/archive/hgewin/system.cpp new file mode 100755 index 0000000..2cbd741 --- /dev/null +++ b/archive/hgewin/system.cpp @@ -0,0 +1,884 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core system functions +** Upgraded to DirectX9 By Chris Xiong, 2013/08/08 +*/ + + +#include "hge_impl.h" + + +#define LOWORDINT(n) ((int)((signed short)(LOWORD(n)))) +#define HIWORDINT(n) ((int)((signed short)(HIWORD(n))))
+static const char* SYSTEM_SRC_FN="hge/system.cpp"; + + +const char *WINDOW_CLASS_NAME = "HGE__WNDCLASS"; + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); + + +int nRef=0; +HGE_Impl* pHGE=0; + + + +BOOL APIENTRY DllMain(HANDLE, DWORD, LPVOID) +{ + return TRUE; +} + + +HGE* CALL hgeCreate(int ver) +{ + if(ver==HGE_VERSION) + return (HGE*)HGE_Impl::_Interface_Get(); + else + return 0; +} + + +HGE_Impl* HGE_Impl::_Interface_Get() +{ + if(!pHGE) pHGE=new HGE_Impl(); + + nRef++; + + return pHGE; +} + + +void CALL HGE_Impl::Release() +{ + nRef--; + + if(!nRef) + { + if(pHGE->hwnd) pHGE->System_Shutdown(); + Resource_RemoveAllPacks(); + delete pHGE; + pHGE=0; + } +} + + +bool CALL HGE_Impl::System_Initiate() +{ + OSVERSIONINFO os_ver; + SYSTEMTIME tm; + MEMORYSTATUS mem_st; + WNDCLASS winclass; + int width, height; + + // Log system info + + System_Log("%s: HGE Started...",SYSTEM_SRC_FN); + + System_Log("%s: hge version: %X.%X", SYSTEM_SRC_FN, HGE_VERSION>>8, HGE_VERSION & 0xFF); + GetLocalTime(&tm); + System_Log("%s: Date: %02d.%02d.%d, %02d:%02d:%02d\n", SYSTEM_SRC_FN, tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond); + + System_Log("%s: Application: %s", SYSTEM_SRC_FN, szWinTitle); + os_ver.dwOSVersionInfoSize=sizeof(os_ver); + GetVersionEx(&os_ver); + System_Log("%s: OS: Windows %ld.%ld.%ld", SYSTEM_SRC_FN, os_ver.dwMajorVersion,os_ver.dwMinorVersion,os_ver.dwBuildNumber); + + GlobalMemoryStatus(&mem_st); + System_Log("%s: Memory: %ldK total, %ldK free\n", SYSTEM_SRC_FN, mem_st.dwTotalPhys/1024L,mem_st.dwAvailPhys/1024L); + + + // Register window class + + winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + winclass.lpfnWndProc = WindowProc; + winclass.cbClsExtra = 0; + winclass.cbWndExtra = 0; + winclass.hInstance = hInstance; + winclass.hCursor = LoadCursor(NULL, IDC_ARROW); + winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + winclass.lpszMenuName = NULL; + winclass.lpszClassName = WINDOW_CLASS_NAME; + if(szIcon) winclass.hIcon = LoadIcon(hInstance, szIcon); + else winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + + if (!RegisterClass(&winclass)) { + _PostError("Can't register window class"); + return false; + } + + // Create window + + width=nScreenWidth + GetSystemMetrics(SM_CXFIXEDFRAME)*2; + height=nScreenHeight + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION); + + rectW.left=(GetSystemMetrics(SM_CXSCREEN)-width)/2; + rectW.top=(GetSystemMetrics(SM_CYSCREEN)-height)/2; + rectW.right=rectW.left+width; + rectW.bottom=rectW.top+height; + styleW=WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE; //WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX; + + rectFS.left=0; + rectFS.top=0; + rectFS.right=nScreenWidth; + rectFS.bottom=nScreenHeight; + styleFS=WS_POPUP|WS_VISIBLE; //WS_POPUP + + if(hwndParent) + { + rectW.left=0; + rectW.top=0; + rectW.right=nScreenWidth; + rectW.bottom=nScreenHeight; + styleW=WS_CHILD|WS_VISIBLE; + bWindowed=true; + } + + if(bWindowed) + hwnd = CreateWindowEx(0, WINDOW_CLASS_NAME, szWinTitle, styleW, + rectW.left, rectW.top, rectW.right-rectW.left, rectW.bottom-rectW.top, + hwndParent, NULL, hInstance, NULL); + else + hwnd = CreateWindowEx(WS_EX_TOPMOST, WINDOW_CLASS_NAME, szWinTitle, styleFS, + 0, 0, 0, 0, + NULL, NULL, hInstance, NULL); + if (!hwnd) + { + _PostError("Can't create window"); + return false; + } + + ShowWindow(hwnd, SW_SHOW); + + // Init subsystems + + timeBeginPeriod(1); + Random_Seed(); + //_InitPowerStatus(); + _InputInit(); + if(!_GfxInit()) { System_Shutdown(); return false; } + if(!_SoundInit()) { System_Shutdown(); return false; } + + System_Log("%s: Init done.\n",SYSTEM_SRC_FN); + + fTime=0.0f; + t0=t0fps=timeGetTime(); + dt=cfps=0; + nFPS=0; + nFPSf=0.0f; + Fcnt=0; + fUpdateFPSDelay=0.0f; + + // Show splash + +#ifdef DEMO + + bool (*func)(); + bool (*rfunc)(); + HWND hwndTmp; + + if(pHGE->bDMO) + { + Sleep(200); + func=(bool(*)())pHGE->System_GetStateFunc(HGE_FRAMEFUNC); + rfunc=(bool(*)())pHGE->System_GetStateFunc(HGE_RENDERFUNC); + hwndTmp=hwndParent; hwndParent=0; + pHGE->System_SetStateFunc(HGE_FRAMEFUNC, DFrame); + pHGE->System_SetStateFunc(HGE_RENDERFUNC, 0); + DInit(); + pHGE->System_Start(); + DDone(); + hwndParent=hwndTmp; + pHGE->System_SetStateFunc(HGE_FRAMEFUNC, func); + pHGE->System_SetStateFunc(HGE_RENDERFUNC, rfunc); + } + +#endif + + // Done + + return true; +} + +void CALL HGE_Impl::System_Shutdown() +{ + System_Log("\n%s: Closing session..",SYSTEM_SRC_FN); + + timeEndPeriod(1); + if(hSearch) { FindClose(hSearch); hSearch=0; } + _ClearQueue(); + _SoundDone(); + _GfxDone(); + //_DonePowerStatus(); + + if(hwnd) + { + //ShowWindow(hwnd, SW_HIDE); + //SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TOOLWINDOW); + //ShowWindow(hwnd, SW_SHOW); + DestroyWindow(hwnd); + hwnd=0; + } + + if(hInstance) UnregisterClass(WINDOW_CLASS_NAME, hInstance); + + System_Log("%s: Session ended.",SYSTEM_SRC_FN); +} + + +bool CALL HGE_Impl::System_Start() +{ + MSG msg; + + if(!hwnd) + { + _PostError("System_Start: System_Initiate wasn't called"); + return false; + } + + if(!procFrameFunc) { + _PostError("System_Start: No frame function defined"); + return false; + } + + bActive=true; + + // MAIN LOOP + + for(;;) + { + + // Process window messages if not in "child mode" + // (if in "child mode" the parent application will do this for us) + + if(!hwndParent) + { + if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) + { + if (msg.message == WM_QUIT) break; + // TranslateMessage(&msg); + DispatchMessage(&msg); + continue; + } + } + + // Check if mouse is over HGE window for Input_IsMouseOver + + _UpdateMouse(); + + // If HGE window is focused or we have the "don't suspend" state - process the main loop + + if(bActive || bDontSuspend) + { + // Ensure we have at least 1ms time step + // to not confuse user's code with 0 + + do { dt=timeGetTime() - t0; } while(dt < 1); + + // If we reached the time for the next frame + // or we just run in unlimited FPS mode, then + // do the stuff + + if(dt >= nFixedDelta) + { + // fDeltaTime = time step in seconds returned by Timer_GetDelta + + fDeltaTime=dt/1000.0f; + + // Cap too large time steps usually caused by lost focus to avoid jerks + + if(fDeltaTime > 0.2f) + { + fDeltaTime = nFixedDelta ? nFixedDelta/1000.0f : 0.01f; + } + + // Update time counter returned Timer_GetTime + + fTime += fDeltaTime; + + // Store current time for the next frame + // and count FPS + + t0=timeGetTime(); + if(t0-t0fps <= 1000) cfps++; + else + { + nFPS=cfps; cfps=0; t0fps=t0; + _UpdatePowerStatus(); + } + ++Fcnt;fUpdateFPSDelay+=fDeltaTime; + if(fUpdateFPSDelay>1) + { + nFPSf=Fcnt/fUpdateFPSDelay; + fUpdateFPSDelay=0.0f; + Fcnt=0; + } + // Do user's stuff + + if(procFrameFunc()) break; + if(procRenderFunc) procRenderFunc(); + + // If if "child mode" - return after processing single frame + + if(hwndParent) break; + + // Clean up input events that were generated by + // WindowProc and weren't handled by user's code + for (int i=1;i<=255;++i) + keylast[i]=Input_GetKeyState(i); + _ClearQueue(); + + // If we use VSYNC - we could afford a little + // sleep to lower CPU usage + + // if(!bWindowed && nHGEFPS==HGEFPS_VSYNC) Sleep(1); + } + + // If we have a fixed frame rate and the time + // for the next frame isn't too close, sleep a bit + + else + { + if(nFixedDelta && dt+3 < nFixedDelta) Sleep(1); + } + } + + // If main loop is suspended - just sleep a bit + // (though not too much to allow instant window + // redraw if requested by OS) + + else Sleep(1); + } + + _ClearQueue(); + + bActive=false; + + return true; +} + +void CALL HGE_Impl::System_SetStateBool(hgeBoolState state, bool value) +{ + switch(state) + { + case HGE_WINDOWED: if(VertArray || hwndParent) break; + if(pD3DDevice && bWindowed != value) + { + if(d3dppW.BackBufferFormat==D3DFMT_UNKNOWN || d3dppFS.BackBufferFormat==D3DFMT_UNKNOWN) break; + + if(bWindowed) GetWindowRect(hwnd, &rectW); + bWindowed=value; + if(bWindowed) d3dpp=&d3dppW; + else d3dpp=&d3dppFS; + + if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16; + else nScreenBPP=32; + + _GfxRestore(); + _AdjustWindow(); + } + else bWindowed=value; + break; + + case HGE_ZBUFFER: if(!pD3DDevice) bZBuffer=value; + break; + + case HGE_TEXTUREFILTER: bTextureFilter=value; + if(pD3DDevice) + { + _render_batch(); + if(bTextureFilter) + { + pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); + pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); + } + else + { + pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT); + pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT); + } + } + break; + + case HGE_USESOUND: if(bUseSound!=value) + { + bUseSound=value; + if(bUseSound && hwnd) _SoundInit(); + if(!bUseSound && hwnd) _SoundDone(); + } + break; + + case HGE_HIDEMOUSE: bHideMouse=value; break; + + case HGE_DONTSUSPEND: bDontSuspend=value; break; + + #ifdef DEMO + case HGE_SHOWSPLASH: bDMO=value; break; + #endif + } +} + +void CALL HGE_Impl::System_SetStateFunc(hgeFuncState state, hgeCallback value) +{ + switch(state) + { + case HGE_FRAMEFUNC: procFrameFunc=value; break; + case HGE_RENDERFUNC: procRenderFunc=value; break; + case HGE_FOCUSLOSTFUNC: procFocusLostFunc=value; break; + case HGE_FOCUSGAINFUNC: procFocusGainFunc=value; break; + case HGE_GFXRESTOREFUNC: procGfxRestoreFunc=value; break; + case HGE_EXITFUNC: procExitFunc=value; break; + } +} + +void CALL HGE_Impl::System_SetStateHwnd(hgeHwndState state, HWND value) +{ + switch(state) + { + case HGE_HWNDPARENT: if(!hwnd) hwndParent=value; break; + } +} + +void CALL HGE_Impl::System_SetStateInt(hgeIntState state, int value) +{ + switch(state) + { + case HGE_SCREENWIDTH: if(!pD3DDevice) nScreenWidth=value; break; + + case HGE_SCREENHEIGHT: if(!pD3DDevice) nScreenHeight=value; break; + + case HGE_SCREENBPP: if(!pD3DDevice) nScreenBPP=value; break; + + case HGE_SAMPLERATE: if(!hOpenAL) nSampleRate=value; + break; + + case HGE_FXVOLUME: nFXVolume=value; + _SetFXVolume(nFXVolume); + break; + + case HGE_MUSVOLUME: nMusVolume=value; + _SetMusVolume(nMusVolume); + break; + + case HGE_STREAMVOLUME: nStreamVolume=value; + _SetStreamVolume(nStreamVolume); + break; + + case HGE_FPS: if(VertArray) break; + + if(pD3DDevice) + { + if((nHGEFPS>=0 && value <0) || (nHGEFPS<0 && value>=0)) + { + if(value==HGEFPS_VSYNC) + { + d3dppW.SwapEffect = D3DSWAPEFFECT_COPY; + d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + else + { + d3dppW.SwapEffect = D3DSWAPEFFECT_COPY; + d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + } + //if(procFocusLostFunc) procFocusLostFunc(); + _GfxRestore(); + //if(procFocusGainFunc) procFocusGainFunc(); + } + } + nHGEFPS=value; + if(nHGEFPS>0) nFixedDelta=int(1000.0f/value); + else nFixedDelta=0; + break; + } +} + +void CALL HGE_Impl::System_SetStateString(hgeStringState state, const char *value) +{ + FILE *hf; + + switch(state) + { + case HGE_ICON: szIcon=value; + if(pHGE->hwnd) SetClassLong(pHGE->hwnd, GCL_HICON, (LONG)LoadIcon(pHGE->hInstance, szIcon)); + break; + case HGE_TITLE: strcpy(szWinTitle,value); + if(pHGE->hwnd) SetWindowText(pHGE->hwnd, szWinTitle); + break; + case HGE_INIFILE: if(value) strcpy(szIniFile,Resource_MakePath(value)); + else szIniFile[0]=0; + break; + case HGE_LOGFILE: if(value) + { + strcpy(szLogFile,Resource_MakePath(value)); + hf=fopen(szLogFile, "w"); + if(!hf) szLogFile[0]=0; + else fclose(hf); + } + else szLogFile[0]=0; + break; + } +} + +bool CALL HGE_Impl::System_GetStateBool(hgeBoolState state) +{ + switch(state) + { + case HGE_WINDOWED: return bWindowed; + case HGE_ZBUFFER: return bZBuffer; + case HGE_TEXTUREFILTER: return bTextureFilter; + case HGE_USESOUND: return bUseSound; + case HGE_DONTSUSPEND: return bDontSuspend; + case HGE_HIDEMOUSE: return bHideMouse; + + #ifdef DEMO + case HGE_SHOWSPLASH: return bDMO; + #endif + } + + return false; +} + +hgeCallback CALL HGE_Impl::System_GetStateFunc(hgeFuncState state) +{ + switch(state) + { + case HGE_FRAMEFUNC: return procFrameFunc; + case HGE_RENDERFUNC: return procRenderFunc; + case HGE_FOCUSLOSTFUNC: return procFocusLostFunc; + case HGE_FOCUSGAINFUNC: return procFocusGainFunc; + case HGE_EXITFUNC: return procExitFunc; + } + + return NULL; +} + +HWND CALL HGE_Impl::System_GetStateHwnd(hgeHwndState state) +{ + switch(state) + { + case HGE_HWND: return hwnd; + case HGE_HWNDPARENT: return hwndParent; + } + + return 0; +} + +int CALL HGE_Impl::System_GetStateInt(hgeIntState state) +{ + switch(state) + { + case HGE_SCREENWIDTH: return nScreenWidth; + case HGE_SCREENHEIGHT: return nScreenHeight; + case HGE_SCREENBPP: return nScreenBPP; + case HGE_SAMPLERATE: return nSampleRate; + case HGE_FXVOLUME: return nFXVolume; + case HGE_MUSVOLUME: return nMusVolume; + case HGE_STREAMVOLUME: return nStreamVolume; + case HGE_FPS: return nHGEFPS; + case HGE_POWERSTATUS: return nPowerStatus; + } + + return 0; +} + +const char* CALL HGE_Impl::System_GetStateString(hgeStringState state) { + switch(state) { + case HGE_ICON: return szIcon; + case HGE_TITLE: return szWinTitle; + case HGE_INIFILE: if(szIniFile[0]) return szIniFile; + else return 0; + case HGE_LOGFILE: if(szLogFile[0]) return szLogFile; + else return 0; + } + + return NULL; +} + +const char* CALL HGE_Impl::System_GetErrorMessage() +{ + return szError; +} + +void CALL HGE_Impl::System_Log(const char *szFormat, ...) +{ + FILE *hf = NULL; + va_list ap; + + if(!szLogFile[0]) return; + + hf = fopen(szLogFile, "a"); + if(!hf) return; + + va_start(ap, szFormat); + vfprintf(hf, szFormat, ap); + va_end(ap); + va_start(ap, szFormat);
+ vfprintf(stderr, szFormat, ap);
+ va_end(ap); + fprintf(hf, "\n"); + fprintf(stderr, "\n"); + + fclose(hf); +} + +bool CALL HGE_Impl::System_Launch(const char *url) +{ + if((DWORD)ShellExecute(pHGE->hwnd, NULL, url, NULL, NULL, SW_SHOWMAXIMIZED)>32) return true; + else return false; +} + +void CALL HGE_Impl::System_Snapshot(const char *filename) +{ + LPDIRECT3DSURFACE9 pSurf; + char *shotname, tempname[_MAX_PATH]; + int i; + + if(!filename) + { + i=0; + shotname=Resource_EnumFiles("shot???.bmp"); + while(shotname) + { + i++; + shotname=Resource_EnumFiles(); + } + sprintf(tempname, "shot%03d.bmp", i); + filename=Resource_MakePath(tempname); + } + + if(pD3DDevice) + { + pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurf); + D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, pSurf, NULL, NULL); + pSurf->Release(); + } +} + +//////// Implementation //////// + + +HGE_Impl::HGE_Impl() +{ + hInstance=GetModuleHandle(0); + hwnd=0; + bActive=false; + szError[0]=0; + + pD3D=0; + pD3DDevice=0; + d3dpp=0; + pTargets=0; + pCurTarget=0; + pScreenSurf=0; + pScreenDepth=0; + pVB=0; + pIB=0; + VertArray=0; + textures=0; + + hOpenAL=0; + bSilent=false; + streams=0; + + hSearch=0; + res=0; + + queue=0; + Char=VKey=Zpos=0; + Xpos=Ypos=0.0f; + bMouseOver=false; + bCaptured=false; + + nHGEFPS=HGEFPS_UNLIMITED; + fTime=0.0f; + fUpdateFPSDelay=0.0f; + fDeltaTime=0.0f; + nFPS=0; + nFPSf=0.0f; + Fcnt=0; + + procFrameFunc=0; + procRenderFunc=0; + procFocusLostFunc=0; + procFocusGainFunc=0; + procGfxRestoreFunc=0; + procExitFunc=0; + szIcon=0; + strcpy(szWinTitle,"HGE"); + nScreenWidth=800; + nScreenHeight=600; + nScreenBPP=32; + bWindowed=false; + bZBuffer=false; + bTextureFilter=true; + szLogFile[0]=0; + szIniFile[0]=0; + bUseSound=true; + nSampleRate=44100; + nFXVolume=100; + nMusVolume=100; + nStreamVolume=100; + nFixedDelta=0; + bHideMouse=true; + bDontSuspend=false; + hwndParent=0; + + nPowerStatus=HGEPWR_UNSUPPORTED; + hKrnl32 = NULL; + lpfnGetSystemPowerStatus = NULL; + +#ifdef DEMO + bDMO=true; +#endif + + + GetModuleFileName(GetModuleHandle(NULL), szAppPath, sizeof(szAppPath)); + int i; + for(i=strlen(szAppPath)-1; i>0; i--) if(szAppPath[i]=='\\') break; + szAppPath[i+1]=0; +} + +void HGE_Impl::_PostError(const char *error) +{ + System_Log(error); + strcpy(szError,error); +} + +void HGE_Impl::_FocusChange(bool bAct) +{ + bActive=bAct; + + if(bActive) + { + if(procFocusGainFunc) procFocusGainFunc(); + } + else + { + if(procFocusLostFunc) procFocusLostFunc(); + } +} + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + bool bActivating; + + switch(msg) + { + case WM_CREATE: + return FALSE; + + case WM_PAINT: + if(pHGE->pD3D && pHGE->procRenderFunc && pHGE->bWindowed) pHGE->procRenderFunc(); + break; + + case WM_DESTROY: + PostQuitMessage(0); + return FALSE; + +/* + case WM_ACTIVATEAPP: + bActivating = (wparam == TRUE); + if(pHGE->pD3D && pHGE->bActive != bActivating) pHGE->_FocusChange(bActivating); + return FALSE; +*/ + case WM_ACTIVATE: + // tricky: we should catch WA_ACTIVE and WA_CLICKACTIVE, + // but only if HIWORD(wParam) (fMinimized) == FALSE (0) + bActivating = (LOWORD(wparam) != WA_INACTIVE) && (HIWORD(wparam) == 0); + if(pHGE->pD3D && pHGE->bActive != bActivating) pHGE->_FocusChange(bActivating); + return FALSE; + + + case WM_SETCURSOR: + if(pHGE->bActive && LOWORD(lparam)==HTCLIENT && pHGE->bHideMouse) SetCursor(NULL); + else SetCursor(LoadCursor(NULL, IDC_ARROW)); + return FALSE; + + case WM_SYSKEYDOWN: + if(wparam == VK_F4) + { + if(pHGE->procExitFunc && !pHGE->procExitFunc()) return FALSE; + return DefWindowProc(hwnd, msg, wparam, lparam); + } + else if(wparam == VK_RETURN) + { + pHGE->System_SetState(HGE_WINDOWED, !pHGE->System_GetState(HGE_WINDOWED)); + return FALSE; + } + else + { + pHGE->_BuildEvent(INPUT_KEYDOWN, wparam, HIWORD(lparam) & 0xFF, (lparam & 0x40000000) ? HGEINP_REPEAT:0, -1, -1); + return FALSE; + } + + case WM_KEYDOWN: + pHGE->_BuildEvent(INPUT_KEYDOWN, wparam, HIWORD(lparam) & 0xFF, (lparam & 0x40000000) ? HGEINP_REPEAT:0, -1, -1); + return FALSE; + case WM_SYSKEYUP: + pHGE->_BuildEvent(INPUT_KEYUP, wparam, HIWORD(lparam) & 0xFF, 0, -1, -1); + return FALSE; + case WM_KEYUP: + pHGE->_BuildEvent(INPUT_KEYUP, wparam, HIWORD(lparam) & 0xFF, 0, -1, -1); + return FALSE; + + case WM_LBUTTONDOWN: + SetFocus(hwnd); + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_MBUTTONDOWN: + SetFocus(hwnd); + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_RBUTTONDOWN: + SetFocus(hwnd); + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + + case WM_LBUTTONDBLCLK: + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_LBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_MBUTTONDBLCLK: + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_MBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_RBUTTONDBLCLK: + pHGE->_BuildEvent(INPUT_MBUTTONDOWN, HGEK_RBUTTON, 0, HGEINP_REPEAT, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + + case WM_LBUTTONUP: + pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_LBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_MBUTTONUP: + pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_MBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case WM_RBUTTONUP: + pHGE->_BuildEvent(INPUT_MBUTTONUP, HGEK_RBUTTON, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + + case WM_MOUSEMOVE: + pHGE->_BuildEvent(INPUT_MOUSEMOVE, 0, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + case 0x020A: // WM_MOUSEWHEEL, GET_WHEEL_DELTA_WPARAM(wparam); + pHGE->_BuildEvent(INPUT_MOUSEWHEEL, short(HIWORD(wparam))/120, 0, 0, LOWORDINT(lparam), HIWORDINT(lparam)); + return FALSE; + + case WM_SIZE: + if(pHGE->pD3D && wparam==SIZE_RESTORED) pHGE->_Resize(LOWORD(lparam), HIWORD(lparam)); + //return FALSE; + break; + + case WM_SYSCOMMAND: + if(wparam==SC_CLOSE) + { + if(pHGE->procExitFunc && !pHGE->procExitFunc()) return FALSE; + pHGE->bActive=false; + return DefWindowProc(hwnd, msg, wparam, lparam); + } + break; + } + + return DefWindowProc(hwnd, msg, wparam, lparam); +} + diff --git a/archive/hgewin/timer.cpp b/archive/hgewin/timer.cpp new file mode 100755 index 0000000..13711c7 --- /dev/null +++ b/archive/hgewin/timer.cpp @@ -0,0 +1,31 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** Core functions implementation: timer +*/ + + +#include "hge_impl.h" + + +float CALL HGE_Impl::Timer_GetTime() +{ + return fTime; +} + +float CALL HGE_Impl::Timer_GetDelta() +{ + return fDeltaTime; +} + +int CALL HGE_Impl::Timer_GetFPS() +{ + return nFPS; +} + +float CALL HGE_Impl::Timer_GetFPSf() +{ + return nFPSf; +} diff --git a/archive/include/hge.h b/archive/include/hge.h new file mode 100644 index 0000000..18d57b9 --- /dev/null +++ b/archive/include/hge.h @@ -0,0 +1,570 @@ +/* +** Haaf's Game Engine 1.8 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** System layer API +*/ + + +#ifndef HGE_H +#define HGE_H + +#ifdef WIN32 +#include <windows.h> +#include <cstddef> +#else +#include "unix_compat.h" +#endif + +#define HGE_VERSION 0x181 + +#ifndef EXPORT +# ifdef HGEDLL +# ifdef _WINDOWS +# define EXPORT __declspec(dllexport) +# elif (__GNUC__ >= 3) +# define EXPORT __attribute__((visibility("default"))) +# else +# define EXPORT +# endif +# else +# define EXPORT +# endif +#endif + +#ifdef _WINDOWS +#define CALL __stdcall +#else +#define CALL +#endif + +#ifdef __BORLANDC__ + #define floorf (float)floor + #define sqrtf (float)sqrt + #define acosf (float)acos + #define atan2f (float)atan2 + #define cosf (float)cos + #define sinf (float)sin + #define powf (float)pow + #define fabsf (float)fabs + #define min(x,y) ((x) < (y)? (x) : (y)) + #define max(x,y) ((x) > (y)? (x) : (y)) +#endif + + + +/* +** Common data types +*/ +#ifdef _WINDOWS +#ifndef DWORD +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef unsigned char BYTE; +#endif +#endif + +/* +** Common math constants +*/ +#ifndef M_PI +#define M_PI 3.14159265358979323846f +#endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923f +#endif +#ifndef M_PI_4 +#define M_PI_4 0.785398163397448309616f +#endif +#ifndef M_1_PI +#define M_1_PI 0.318309886183790671538f +#endif +#ifndef M_2_PI +#define M_2_PI 0.636619772367581343076f +#endif + + +/* +** HGE Handle types +*/ +typedef size_t HTEXTURE; +typedef size_t HTARGET; +typedef size_t HEFFECT; +typedef size_t HMUSIC; +typedef size_t HSTREAM; +typedef size_t HCHANNEL; + + +/* +** Hardware color macros +*/ +#define ARGB(a,r,g,b) ((DWORD(a)<<24) + (DWORD(r)<<16) + (DWORD(g)<<8) + DWORD(b)) +#define GETA(col) ((col)>>24) +#define GETR(col) (((col)>>16) & 0xFF) +#define GETG(col) (((col)>>8) & 0xFF) +#define GETB(col) ((col) & 0xFF) +#define SETA(col,a) (((col) & 0x00FFFFFF) + (DWORD(a)<<24)) +#define SETR(col,r) (((col) & 0xFF00FFFF) + (DWORD(r)<<16)) +#define SETG(col,g) (((col) & 0xFFFF00FF) + (DWORD(g)<<8)) +#define SETB(col,b) (((col) & 0xFFFFFF00) + DWORD(b)) + + +/* +** HGE Blending constants +*/ +#define BLEND_COLORADD 1 +#define BLEND_COLORMUL 0 +#define BLEND_ALPHABLEND 2 +#define BLEND_ALPHAADD 0 +#define BLEND_ZWRITE 4 +#define BLEND_NOZWRITE 0 + +#define BLEND_DEFAULT (BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE) +#define BLEND_DEFAULT_Z (BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_ZWRITE) + + +/* +** HGE System state constants +*/ +enum hgeBoolState +{ + HGE_WINDOWED = 1, // bool run in window? (default: false) + HGE_ZBUFFER = 2, // bool use z-buffer? (default: false) + HGE_TEXTUREFILTER = 3, // bool texture filtering? (default: true) + + HGE_USESOUND = 4, // bool use BASS for sound? (default: true) + + HGE_DONTSUSPEND = 5, // bool focus lost:suspend? (default: false) + HGE_HIDEMOUSE = 6, // bool hide system cursor? (default: true) + + HGE_SHOWSPLASH = 7, // bool hide system cursor? (default: true) + + HGEBOOLSTATE_FORCE_DWORD = 0x7FFFFFFF +}; + +enum hgeFuncState +{ + HGE_FRAMEFUNC = 8, // bool*() frame function (default: NULL) (you MUST set this) + HGE_RENDERFUNC = 9, // bool*() render function (default: NULL) + HGE_FOCUSLOSTFUNC = 10, // bool*() focus lost function (default: NULL) + HGE_FOCUSGAINFUNC = 11, // bool*() focus gain function (default: NULL) + HGE_GFXRESTOREFUNC = 12, // bool*() exit function (default: NULL) + HGE_EXITFUNC = 13, // bool*() exit function (default: NULL) + + HGEFUNCSTATE_FORCE_DWORD = 0x7FFFFFFF +}; + +enum hgeHwndState +{ + HGE_HWND = 15, // int window handle: read only + HGE_HWNDPARENT = 16, // int parent win handle (default: 0) + + HGEHWNDSTATE_FORCE_DWORD = 0x7FFFFFFF +}; + +enum hgeIntState +{ + HGE_SCREENWIDTH = 17, // int screen width (default: 800) + HGE_SCREENHEIGHT = 18, // int screen height (default: 600) + HGE_SCREENBPP = 19, // int screen bitdepth (default: 32) (desktop bpp in windowed mode) + + HGE_SAMPLERATE = 20, // int sample rate (default: 44100) + HGE_FXVOLUME = 21, // int global fx volume (default: 100) + HGE_MUSVOLUME = 22, // int global music volume (default: 100) + HGE_STREAMVOLUME = 23, // int global music volume (default: 100) + + HGE_FPS = 24, // int fixed fps (default: HGEFPS_UNLIMITED) + + HGE_POWERSTATUS = 25, // int battery life percent + status + + HGE_ORIGSCREENWIDTH = 30, // int original screen width (default: 800 ... not valid until hge->System_Initiate()!) + HGE_ORIGSCREENHEIGHT = 31, // int original screen height (default: 600 ... not valid until hge->System_Initiate()!)) + + HGEINTSTATE_FORCE_DWORD = 0x7FFFFFF +}; + +enum hgeStringState +{ + HGE_ICON = 26, // char* icon resource (default: NULL) + HGE_TITLE = 27, // char* window title (default: "HGE") + + HGE_INIFILE = 28, // char* ini file (default: NULL) (meaning no file) + HGE_LOGFILE = 29, // char* log file (default: NULL) (meaning no file) + + HGESTRINGSTATE_FORCE_DWORD = 0x7FFFFFFF +}; + +/* +** Callback protoype used by HGE +*/ +typedef bool (*hgeCallback)(); + + +/* +** HGE_FPS system state special constants +*/ +#define HGEFPS_UNLIMITED 0 +#define HGEFPS_VSYNC -1 + + +/* +** HGE_POWERSTATUS system state special constants +*/ +#define HGEPWR_AC -1 +#define HGEPWR_UNSUPPORTED -2 + + +/* +** HGE Primitive type constants +*/ +#define HGEPRIM_LINES 2 +#define HGEPRIM_TRIPLES 3 +#define HGEPRIM_QUADS 4 + + +/* +** HGE Vertex structure +*/ +struct hgeVertex +{ + float x, y; // screen position + float z; // Z-buffer depth 0..1 + DWORD col; // color + float tx, ty; // texture coordinates +}; + + +/* +** HGE Triple structure +*/ +struct hgeTriple +{ + hgeVertex v[3]; + HTEXTURE tex; + int blend; +}; + + +/* +** HGE Quad structure +*/ +struct hgeQuad +{ + hgeVertex v[4]; + HTEXTURE tex; + int blend; +}; + + +/* +** HGE Input Event structure +*/ +struct hgeInputEvent +{ + int type; // event type + int key; // key code + int flags; // event flags + int chr; // character code + int wheel; // wheel shift + float x; // mouse cursor x-coordinate + float y; // mouse cursor y-coordinate +}; + + +/* +** HGE Input Event type constants +*/ +#define INPUT_KEYDOWN 1 +#define INPUT_KEYUP 2 +#define INPUT_MBUTTONDOWN 3 +#define INPUT_MBUTTONUP 4 +#define INPUT_MOUSEMOVE 5 +#define INPUT_MOUSEWHEEL 6 + + +/* +** HGE Input Event flags +*/ +#define HGEINP_SHIFT 1 +#define HGEINP_CTRL 2 +#define HGEINP_ALT 4 +#define HGEINP_CAPSLOCK 8 +#define HGEINP_SCROLLLOCK 16 +#define HGEINP_NUMLOCK 32 +#define HGEINP_REPEAT 64 + + +/* +** HGE Interface class +*/ +class HGE +{ +public: + HGE() {} + virtual ~HGE() {}; + + virtual void CALL Release() = 0; + + virtual bool CALL System_Initiate() = 0; + virtual void CALL System_Shutdown() = 0; + virtual bool CALL System_Start() = 0; + virtual const char* CALL System_GetErrorMessage() = 0; + virtual void CALL System_Log(const char *format, ...) = 0; + virtual bool CALL System_Launch(const char *url) = 0; + virtual void CALL System_Snapshot(const char *filename=0) = 0; + +private: + virtual void CALL System_SetStateBool (hgeBoolState state, bool value) = 0; + virtual void CALL System_SetStateFunc (hgeFuncState state, hgeCallback value) = 0; + virtual void CALL System_SetStateHwnd (hgeHwndState state, HWND value) = 0; + virtual void CALL System_SetStateInt (hgeIntState state, int value) = 0; + virtual void CALL System_SetStateString(hgeStringState state, const char *value) = 0; + virtual bool CALL System_GetStateBool (hgeBoolState state) = 0; + virtual hgeCallback CALL System_GetStateFunc (hgeFuncState state) = 0; + virtual HWND CALL System_GetStateHwnd (hgeHwndState state) = 0; + virtual int CALL System_GetStateInt (hgeIntState state) = 0; + virtual const char* CALL System_GetStateString(hgeStringState state) = 0; + +public: + inline void System_SetState(hgeBoolState state, bool value) { System_SetStateBool (state, value); } + inline void System_SetState(hgeFuncState state, hgeCallback value) { System_SetStateFunc (state, value); } + inline void System_SetState(hgeHwndState state, HWND value) { System_SetStateHwnd (state, value); } + inline void System_SetState(hgeIntState state, int value) { System_SetStateInt (state, value); } + inline void System_SetState(hgeStringState state, const char *value) { System_SetStateString(state, value); } + inline bool System_GetState(hgeBoolState state) { return System_GetStateBool (state); } + inline hgeCallback System_GetState(hgeFuncState state) { return System_GetStateFunc (state); } + inline HWND System_GetState(hgeHwndState state) { return System_GetStateHwnd (state); } + inline int System_GetState(hgeIntState state) { return System_GetStateInt (state); } + inline const char* System_GetState(hgeStringState state) { return System_GetStateString(state); } + + virtual void* CALL Resource_Load(const char *filename, DWORD *size=0) = 0; + virtual void CALL Resource_Free(void *res) = 0; + virtual bool CALL Resource_AttachPack(const char *filename, const char *password=0) = 0; + virtual void CALL Resource_RemovePack(const char *filename) = 0; + virtual void CALL Resource_RemoveAllPacks() = 0; + virtual char* CALL Resource_MakePath(const char *filename=0) = 0; + virtual char* CALL Resource_EnumFiles(const char *wildcard=0) = 0; + virtual char* CALL Resource_EnumFolders(const char *wildcard=0) = 0; + + virtual void CALL Ini_SetInt(const char *section, const char *name, int value) = 0; + virtual int CALL Ini_GetInt(const char *section, const char *name, int def_val) = 0; + virtual void CALL Ini_SetFloat(const char *section, const char *name, float value) = 0; + virtual float CALL Ini_GetFloat(const char *section, const char *name, float def_val) = 0; + virtual void CALL Ini_SetString(const char *section, const char *name, const char *value) = 0; + virtual char* CALL Ini_GetString(const char *section, const char *name, const char *def_val) = 0; + + virtual void CALL Random_Seed(int seed=0) = 0; + virtual int CALL Random_Int(int min, int max) = 0; + virtual float CALL Random_Float(float min, float max) = 0; + + virtual float CALL Timer_GetTime() = 0; + virtual float CALL Timer_GetDelta() = 0; + virtual int CALL Timer_GetFPS() = 0; + virtual float CALL Timer_GetFPSf() = 0; + + virtual HEFFECT CALL Effect_Load(const char *filename, DWORD size=0) = 0; + virtual void CALL Effect_Free(HEFFECT eff) = 0; + virtual HCHANNEL CALL Effect_Play(HEFFECT eff) = 0; + virtual HCHANNEL CALL Effect_PlayEx(HEFFECT eff, float volume=1.0, float pan=0.0, float pitch=1.0f, bool loop=false) = 0; + + virtual HMUSIC CALL Music_Load(const char *filename, DWORD size=0) = 0; + virtual void CALL Music_Free(HMUSIC mus) = 0; + virtual HCHANNEL CALL Music_Play(HMUSIC mus, bool loop, int volume = 100, int order = -1, int row = -1) = 0; + virtual void CALL Music_SetAmplification(HMUSIC music, int ampl) = 0; + virtual int CALL Music_GetAmplification(HMUSIC music) = 0; + virtual int CALL Music_GetLength(HMUSIC music) = 0; + virtual void CALL Music_SetPos(HMUSIC music, int order, int row) = 0; + virtual bool CALL Music_GetPos(HMUSIC music, int *order, int *row) = 0; + virtual void CALL Music_SetInstrVolume(HMUSIC music, int instr, int volume) = 0; + virtual int CALL Music_GetInstrVolume(HMUSIC music, int instr) = 0; + virtual void CALL Music_SetChannelVolume(HMUSIC music, int channel, int volume) = 0; + virtual int CALL Music_GetChannelVolume(HMUSIC music, int channel) = 0; + + virtual HSTREAM CALL Stream_Load(const char *filename, DWORD size=0) = 0; + virtual void CALL Stream_Free(HSTREAM stream) = 0; + virtual HCHANNEL CALL Stream_Play(HSTREAM stream, bool loop, int volume = 100) = 0; + + virtual void CALL Channel_SetPanning(HCHANNEL chn, float pan) = 0; + virtual void CALL Channel_SetVolume(HCHANNEL chn, float volume) = 0; + virtual void CALL Channel_SetPitch(HCHANNEL chn, float pitch) = 0; + virtual void CALL Channel_Pause(HCHANNEL chn) = 0; + virtual void CALL Channel_Resume(HCHANNEL chn) = 0; + virtual void CALL Channel_Stop(HCHANNEL chn) = 0; + virtual void CALL Channel_PauseAll() = 0; + virtual void CALL Channel_ResumeAll() = 0; + virtual void CALL Channel_StopAll() = 0; + virtual bool CALL Channel_IsPlaying(HCHANNEL chn) = 0; + virtual float CALL Channel_GetLength(HCHANNEL chn) = 0; + virtual float CALL Channel_GetPos(HCHANNEL chn) = 0; + virtual void CALL Channel_SetPos(HCHANNEL chn, float fSeconds) = 0; + virtual int CALL Channel_GetPos_BySample(HCHANNEL chn) = 0; + virtual void CALL Channel_SetPos_BySample(HCHANNEL chn, int iSample) = 0; + virtual void CALL Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan = -101, float pitch = -1) = 0; + virtual bool CALL Channel_IsSliding(HCHANNEL channel) = 0; + + virtual void CALL Input_GetMousePos(float *x, float *y) = 0; + virtual void CALL Input_SetMousePos(float x, float y) = 0; + virtual int CALL Input_GetMouseWheel() = 0; + virtual bool CALL Input_IsMouseOver() = 0; + virtual bool CALL Input_KeyDown(int key) = 0; + virtual bool CALL Input_KeyUp(int key) = 0; + virtual bool CALL Input_GetKeyState(int key) = 0; + virtual int CALL Input_GetKeyStateEx(int key) = 0; + virtual const char* CALL Input_GetKeyName(int key) = 0; + virtual int CALL Input_GetKey() = 0; + virtual int CALL Input_GetChar() = 0; + virtual bool CALL Input_GetEvent(hgeInputEvent *event) = 0; + + virtual bool CALL Gfx_BeginScene(HTARGET target=0) = 0; + virtual void CALL Gfx_EndScene() = 0; + virtual void CALL Gfx_Clear(DWORD color) = 0; + virtual void CALL Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color=0xFFFFFFFF, float z=0.5f) = 0; + virtual void CALL Gfx_RenderTriple(const hgeTriple *triple) = 0; + virtual void CALL Gfx_RenderQuad(const hgeQuad *quad) = 0; + virtual hgeVertex* CALL Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim) = 0; + virtual void CALL Gfx_FinishBatch(int nprim) = 0; + virtual void CALL Gfx_SetClipping(int x=0, int y=0, int w=0, int h=0) = 0; + virtual void CALL Gfx_SetTransform(float x=0, float y=0, float dx=0, float dy=0, float rot=0, float hscale=0, float vscale=0) = 0; + + virtual HTARGET CALL Target_Create(int width, int height, bool zbuffer) = 0; + virtual void CALL Target_Free(HTARGET target) = 0; + virtual HTEXTURE CALL Target_GetTexture(HTARGET target) = 0; + + virtual HTEXTURE CALL Texture_Create(int width, int height) = 0; + virtual HTEXTURE CALL Texture_Load(const char *filename, DWORD size=0, bool bMipmap=false) = 0; + virtual void CALL Texture_Free(HTEXTURE tex) = 0; + virtual int CALL Texture_GetWidth(HTEXTURE tex, bool bOriginal=false) = 0; + virtual int CALL Texture_GetHeight(HTEXTURE tex, bool bOriginal=false) = 0; + virtual DWORD* CALL Texture_Lock(HTEXTURE tex, bool bReadOnly=true, int left=0, int top=0, int width=0, int height=0) = 0; + virtual void CALL Texture_Unlock(HTEXTURE tex) = 0; +}; + +extern "C" { EXPORT HGE * CALL hgeCreate(int ver); } + + +/* +** HGE Virtual-key codes +*/ +#define HGEK_LBUTTON 0x01 +#define HGEK_RBUTTON 0x02 +#define HGEK_MBUTTON 0x04 + +#define HGEK_ESCAPE 0x1B +#define HGEK_BACKSPACE 0x08 +#define HGEK_TAB 0x09 +#define HGEK_ENTER 0x0D +#define HGEK_SPACE 0x20 + +#define HGEK_SHIFT 0x10 +#define HGEK_CTRL 0x11 +#define HGEK_ALT 0x12 + +#define HGEK_LWIN 0x5B +#define HGEK_RWIN 0x5C +#define HGEK_APPS 0x5D + +#define HGEK_PAUSE 0x13 +#define HGEK_CAPSLOCK 0x14 +#define HGEK_NUMLOCK 0x90 +#define HGEK_SCROLLLOCK 0x91 + +#define HGEK_PGUP 0x21 +#define HGEK_PGDN 0x22 +#define HGEK_HOME 0x24 +#define HGEK_END 0x23 +#define HGEK_INSERT 0x2D +#define HGEK_DELETE 0x2E + +#define HGEK_LEFT 0x25 +#define HGEK_UP 0x26 +#define HGEK_RIGHT 0x27 +#define HGEK_DOWN 0x28 + +#define HGEK_0 0x30 +#define HGEK_1 0x31 +#define HGEK_2 0x32 +#define HGEK_3 0x33 +#define HGEK_4 0x34 +#define HGEK_5 0x35 +#define HGEK_6 0x36 +#define HGEK_7 0x37 +#define HGEK_8 0x38 +#define HGEK_9 0x39 + +#define HGEK_A 0x41 +#define HGEK_B 0x42 +#define HGEK_C 0x43 +#define HGEK_D 0x44 +#define HGEK_E 0x45 +#define HGEK_F 0x46 +#define HGEK_G 0x47 +#define HGEK_H 0x48 +#define HGEK_I 0x49 +#define HGEK_J 0x4A +#define HGEK_K 0x4B +#define HGEK_L 0x4C +#define HGEK_M 0x4D +#define HGEK_N 0x4E +#define HGEK_O 0x4F +#define HGEK_P 0x50 +#define HGEK_Q 0x51 +#define HGEK_R 0x52 +#define HGEK_S 0x53 +#define HGEK_T 0x54 +#define HGEK_U 0x55 +#define HGEK_V 0x56 +#define HGEK_W 0x57 +#define HGEK_X 0x58 +#define HGEK_Y 0x59 +#define HGEK_Z 0x5A + +#define HGEK_GRAVE 0xC0 +#define HGEK_MINUS 0xBD +#define HGEK_EQUALS 0xBB +#define HGEK_BACKSLASH 0xDC +#define HGEK_LBRACKET 0xDB +#define HGEK_RBRACKET 0xDD +#define HGEK_SEMICOLON 0xBA +#define HGEK_APOSTROPHE 0xDE +#define HGEK_COMMA 0xBC +#define HGEK_PERIOD 0xBE +#define HGEK_SLASH 0xBF + +#define HGEK_NUMPAD0 0x60 +#define HGEK_NUMPAD1 0x61 +#define HGEK_NUMPAD2 0x62 +#define HGEK_NUMPAD3 0x63 +#define HGEK_NUMPAD4 0x64 +#define HGEK_NUMPAD5 0x65 +#define HGEK_NUMPAD6 0x66 +#define HGEK_NUMPAD7 0x67 +#define HGEK_NUMPAD8 0x68 +#define HGEK_NUMPAD9 0x69 + +#define HGEK_MULTIPLY 0x6A +#define HGEK_DIVIDE 0x6F +#define HGEK_ADD 0x6B +#define HGEK_SUBTRACT 0x6D +#define HGEK_DECIMAL 0x6E + +#define HGEK_F1 0x70 +#define HGEK_F2 0x71 +#define HGEK_F3 0x72 +#define HGEK_F4 0x73 +#define HGEK_F5 0x74 +#define HGEK_F6 0x75 +#define HGEK_F7 0x76 +#define HGEK_F8 0x77 +#define HGEK_F9 0x78 +#define HGEK_F10 0x79 +#define HGEK_F11 0x7A +#define HGEK_F12 0x7B + +#define HGEKST_NONE 0 +#define HGEKST_HIT 1 +#define HGEKST_KEEP 2 +#define HGEKST_RELEASE 3 + +#endif + diff --git a/archive/include/hgeanim.h b/archive/include/hgeanim.h new file mode 100644 index 0000000..7c5f237 --- /dev/null +++ b/archive/include/hgeanim.h @@ -0,0 +1,69 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeAnimation helper class header +*/ + + +#ifndef HGEANIM_H +#define HGEANIM_H + + +#include "hgesprite.h" + + +#define HGEANIM_FWD 0 +#define HGEANIM_REV 1 +#define HGEANIM_PINGPONG 2 +#define HGEANIM_NOPINGPONG 0 +#define HGEANIM_LOOP 4 +#define HGEANIM_NOLOOP 0 + + +/* +** HGE Animation class +*/ +class hgeAnimation : public hgeSprite +{ +public: + hgeAnimation(HTEXTURE tex, int nframes, float FPS, float x, float y, float w, float h); + hgeAnimation(const hgeAnimation &anim); + + void Play(); + void Stop() { bPlaying=false; } + void Resume() { bPlaying=true; } + void Update(float fDeltaTime); + bool IsPlaying() const { return bPlaying; } + + void SetTexture(HTEXTURE tex) { hgeSprite::SetTexture(tex); orig_width = hge->Texture_GetWidth(tex, true); } + void SetTextureRect(float x1, float y1, float x2, float y2) { hgeSprite::SetTextureRect(x1,y1,x2,y2); SetFrame(nCurFrame); } + void SetMode(int mode); + void SetSpeed(float FPS) { fSpeed=1.0f/FPS; } + void SetFrame(int n); + void SetFrames(int n) { nFrames=n; } + + int GetMode() const { return Mode; } + float GetSpeed() const { return 1.0f/fSpeed; } + int GetFrame() const { return nCurFrame; } + int GetFrames() const { return nFrames; } + +private: + hgeAnimation(); + + int orig_width; + + bool bPlaying; + + float fSpeed; + float fSinceLastFrame; + + int Mode; + int nDelta; + int nFrames; + int nCurFrame; +}; + + +#endif diff --git a/archive/include/hgecolor.h b/archive/include/hgecolor.h new file mode 100644 index 0000000..7cd4d82 --- /dev/null +++ b/archive/include/hgecolor.h @@ -0,0 +1,80 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeColor*** helper classes +*/ + + +#ifndef HGECOLOR_H +#define HGECOLOR_H + + +#include "hge.h" + + +#define hgeColor hgeColorRGB + +inline void ColorClamp(float &x) { if(x<0.0f) x=0.0f; if(x>1.0f) x=1.0f; } + + +class hgeColorRGB +{ +public: + float r,g,b,a; + + hgeColorRGB(float _r, float _g, float _b, float _a) { r=_r; g=_g; b=_b; a=_a; } + hgeColorRGB(DWORD col) { SetHWColor(col); } + hgeColorRGB() { r=g=b=a=0; } + + hgeColorRGB operator- (const hgeColorRGB &c) const { return hgeColorRGB(r-c.r, g-c.g, b-c.b, a-c.a); } + hgeColorRGB operator+ (const hgeColorRGB &c) const { return hgeColorRGB(r+c.r, g+c.g, b+c.b, a+c.a); } + hgeColorRGB operator* (const hgeColorRGB &c) const { return hgeColorRGB(r*c.r, g*c.g, b*c.b, a*c.a); } + hgeColorRGB& operator-= (const hgeColorRGB &c) { r-=c.r; g-=c.g; b-=c.b; a-=c.a; return *this; } + hgeColorRGB& operator+= (const hgeColorRGB &c) { r+=c.r; g+=c.g; b+=c.b; a+=c.a; return *this; } + bool operator== (const hgeColorRGB &c) const { return (r==c.r && g==c.g && b==c.b && a==c.a); } + bool operator!= (const hgeColorRGB &c) const { return (r!=c.r || g!=c.g || b!=c.b || a!=c.a); } + + hgeColorRGB operator/ (const float scalar) const { return hgeColorRGB(r/scalar, g/scalar, b/scalar, a/scalar); } + hgeColorRGB operator* (const float scalar) const { return hgeColorRGB(r*scalar, g*scalar, b*scalar, a*scalar); } + hgeColorRGB& operator*= (const float scalar) { r*=scalar; g*=scalar; b*=scalar; a*=scalar; return *this; } + + void Clamp() { ColorClamp(r); ColorClamp(g); ColorClamp(b); ColorClamp(a); } + void SetHWColor(DWORD col) { a = (col>>24)/255.0f; r = ((col>>16) & 0xFF)/255.0f; g = ((col>>8) & 0xFF)/255.0f; b = (col & 0xFF)/255.0f; } + DWORD GetHWColor() const { return (DWORD(a*255.0f)<<24) + (DWORD(r*255.0f)<<16) + (DWORD(g*255.0f)<<8) + DWORD(b*255.0f); } +}; + +inline hgeColorRGB operator* (const float sc, const hgeColorRGB &c) { return c*sc; } + + +class hgeColorHSV +{ +public: + float h,s,v,a; + + hgeColorHSV(float _h, float _s, float _v, float _a) { h=_h; s=_s; v=_v; a=_a; } + hgeColorHSV(DWORD col) { SetHWColor(col); } + hgeColorHSV() { h=s=v=a=0; } + + hgeColorHSV operator- (const hgeColorHSV &c) const { return hgeColorHSV(h-c.h, s-c.s, v-c.v, a-c.a); } + hgeColorHSV operator+ (const hgeColorHSV &c) const { return hgeColorHSV(h+c.h, s+c.s, v+c.v, a+c.a); } + hgeColorHSV operator* (const hgeColorHSV &c) const { return hgeColorHSV(h*c.h, s*c.s, v*c.v, a*c.a); } + hgeColorHSV& operator-= (const hgeColorHSV &c) { h-=c.h; s-=c.s; v-=c.v; a-=c.a; return *this; } + hgeColorHSV& operator+= (const hgeColorHSV &c) { h+=c.h; s+=c.s; v+=c.v; a+=c.a; return *this; } + bool operator== (const hgeColorHSV &c) const { return (h==c.h && s==c.s && v==c.v && a==c.a); } + bool operator!= (const hgeColorHSV &c) const { return (h!=c.h || s!=c.s || v!=c.v || a!=c.a); } + + hgeColorHSV operator/ (const float scalar) const { return hgeColorHSV(h/scalar, s/scalar, v/scalar, a/scalar); } + hgeColorHSV operator* (const float scalar) const { return hgeColorHSV(h*scalar, s*scalar, v*scalar, a*scalar); } + hgeColorHSV& operator*= (const float scalar) { h*=scalar; s*=scalar; v*=scalar; a*=scalar; return *this; } + + void Clamp() { ColorClamp(h); ColorClamp(s); ColorClamp(v); ColorClamp(a); } + void SetHWColor(DWORD col); + DWORD GetHWColor() const; +}; + +inline hgeColorHSV operator* (const float sc, const hgeColorHSV &c) { return c*sc; } + + +#endif diff --git a/archive/include/hgedistort.h b/archive/include/hgedistort.h new file mode 100644 index 0000000..3c8f449 --- /dev/null +++ b/archive/include/hgedistort.h @@ -0,0 +1,66 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeDistortionMesh helper class header +*/ + + +#ifndef HGEDISTORT_H +#define HGEDISTORT_H + + +#include "hge.h" + + +#define HGEDISP_NODE 0 +#define HGEDISP_TOPLEFT 1 +#define HGEDISP_CENTER 2 + +/* +** HGE Distortion mesh class +*/ +class hgeDistortionMesh +{ +public: + hgeDistortionMesh(int cols, int rows); + hgeDistortionMesh(const hgeDistortionMesh &dm); + ~hgeDistortionMesh(); + + hgeDistortionMesh& operator= (const hgeDistortionMesh &dm); + + void Render(float x, float y); + void Clear(DWORD col=0xFFFFFFFF, float z=0.5f); + + void SetTexture(HTEXTURE tex); + void SetTextureRect(float x, float y, float w, float h); + void SetBlendMode(int blend); + void SetZ(int col, int row, float z); + void SetColor(int col, int row, DWORD color); + void SetDisplacement(int col, int row, float dx, float dy, int ref); + + HTEXTURE GetTexture() const {return quad.tex;} + void GetTextureRect(float *x, float *y, float *w, float *h) const { *x=tx; *y=ty; *w=width; *h=height; } + int GetBlendMode() const { return quad.blend; } + float GetZ(int col, int row) const; + DWORD GetColor(int col, int row) const; + void GetDisplacement(int col, int row, float *dx, float *dy, int ref) const; + + int GetRows() { return nRows; } + int GetCols() { return nCols; } + +private: + hgeDistortionMesh(); + + static HGE *hge; + + hgeVertex *disp_array; + int nRows, nCols; + float cellw,cellh; + float tx,ty,width,height; + hgeQuad quad; +}; + + +#endif diff --git a/archive/include/hgefont.h b/archive/include/hgefont.h new file mode 100644 index 0000000..403d307 --- /dev/null +++ b/archive/include/hgefont.h @@ -0,0 +1,94 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeFont helper class header +*/ + + +#ifndef HGEFONT_H +#define HGEFONT_H + + +#include "hge.h" +#include "hgesprite.h" + + +#define HGETEXT_LEFT 0 +#define HGETEXT_RIGHT 1 +#define HGETEXT_CENTER 2 +#define HGETEXT_HORZMASK 0x03 + +#define HGETEXT_TOP 0 +#define HGETEXT_BOTTOM 4 +#define HGETEXT_MIDDLE 8 +#define HGETEXT_VERTMASK 0x0C + +/* +** HGE Font class +*/ +class hgeFont +{ +public: + hgeFont(const char *filename, bool bMipmap=false); + ~hgeFont(); + + void Render(float x, float y, int align, const char *string); + void printf(float x, float y, int align, const char *format, ...); + void printfb(float x, float y, float w, float h, int align, const char *format, ...); + + void SetColor(DWORD col); + void SetZ(float z); + void SetBlendMode(int blend); + void SetScale(float scale) {fScale=scale;} + void SetProportion(float prop) { fProportion=prop; } + void SetRotation(float rot) {fRot=rot;} + void SetTracking(float tracking) {fTracking=tracking;} + void SetSpacing(float spacing) {fSpacing=spacing;} + + DWORD GetColor() const {return dwCol;} + float GetZ() const {return fZ;} + int GetBlendMode() const {return nBlend;} + float GetScale() const {return fScale;} + float GetProportion() const { return fProportion; } + float GetRotation() const {return fRot;} + float GetTracking() const {return fTracking;} + float GetSpacing() const {return fSpacing;} + + hgeSprite* GetSprite(char chr) const { return letters[(unsigned char)chr]; } + float GetPreWidth(char chr) const { return pre[(unsigned char)chr]; } + float GetPostWidth(char chr) const { return post[(unsigned char)chr]; } + float GetHeight() const { return fHeight; } + float GetStringWidth(const char *string, bool bMultiline=true) const; + + HTEXTURE GetTexture(){return hTexture;} +private: + hgeFont(); + hgeFont(const hgeFont &fnt); + hgeFont& operator= (const hgeFont &fnt); + + char* _get_line(char *file, char *line); + + static HGE *hge; + + static char buffer[1024]; + + HTEXTURE hTexture; + hgeSprite* letters[256]; + float pre[256]; + float post[256]; + float fHeight; + float fScale; + float fProportion; + float fRot; + float fTracking; + float fSpacing; + + DWORD dwCol; + float fZ; + int nBlend; +}; + + +#endif diff --git a/archive/include/hgegui.h b/archive/include/hgegui.h new file mode 100644 index 0000000..7e2144b --- /dev/null +++ b/archive/include/hgegui.h @@ -0,0 +1,126 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeGUI helper classes header +*/ + + +#ifndef HGEGUI_H +#define HGEGUI_H + + +#include "hge.h" +#include "hgesprite.h" +#include "hgerect.h" + + +#define HGEGUI_NONAVKEYS 0 +#define HGEGUI_LEFTRIGHT 1 +#define HGEGUI_UPDOWN 2 +#define HGEGUI_CYCLED 4 + +class hgeGUI; + +/* +** hgeGUIObject +*/ +class hgeGUIObject +{ +public: + hgeGUIObject() { hge=hgeCreate(HGE_VERSION); color=0xFFFFFFFF; } + virtual ~hgeGUIObject() { hge->Release(); } + + virtual void Render() = 0; + virtual void Update(float dt) {} + + virtual void Enter() {} + virtual void Leave() {} + virtual void Reset() {} + virtual bool IsDone() { return true; } + virtual void Focus(bool bFocused) {} + virtual void MouseOver(bool bOver) {} + + virtual bool MouseMove(float x, float y) { return false; } + virtual bool MouseLButton(bool bDown) { return false; } + virtual bool MouseRButton(bool bDown) { return false; } + virtual bool MouseWheel(int nNotches) { return false; } + virtual bool KeyClick(int key, int chr) { return false; } + + virtual void SetColor(DWORD _color) { color=_color; } + + int id; + bool bStatic; + bool bVisible; + bool bEnabled; + hgeRect rect; + DWORD color; + + hgeGUI *gui; + hgeGUIObject *next; + hgeGUIObject *prev; + +protected: + hgeGUIObject(const hgeGUIObject &go); + hgeGUIObject& operator= (const hgeGUIObject &go); + + static HGE *hge; +}; + + +/* +** hgeGUI +*/ +class hgeGUI +{ +public: + hgeGUI(); + ~hgeGUI(); + + void AddCtrl(hgeGUIObject *ctrl); + void DelCtrl(int id); + hgeGUIObject* GetCtrl(int id) const; + + void MoveCtrl(int id, float x, float y); + void ShowCtrl(int id, bool bVisible); + void EnableCtrl(int id, bool bEnabled); + + void SetNavMode(int mode); + void SetCursor(hgeSprite *spr); + void SetColor(DWORD color); + void SetFocus(int id); + int GetFocus() const; + + void Enter(); + void Leave(); + void Reset(); + void Move(float dx, float dy); + + int Update(float dt); + void Render(); + +private: + hgeGUI(const hgeGUI &); + hgeGUI& operator= (const hgeGUI&); + bool ProcessCtrl(hgeGUIObject *ctrl); + + static HGE *hge; + + hgeGUIObject *ctrls; + hgeGUIObject *ctrlLock; + hgeGUIObject *ctrlFocus; + hgeGUIObject *ctrlOver; + + int navmode; + int nEnterLeave; + hgeSprite *sprCursor; + + float mx,my; + int nWheel; + bool bLPressed, bLReleased; + bool bRPressed, bRReleased; +}; + + +#endif diff --git a/archive/include/hgeguictrls.h b/archive/include/hgeguictrls.h new file mode 100644 index 0000000..8a1addd --- /dev/null +++ b/archive/include/hgeguictrls.h @@ -0,0 +1,150 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeGUI default controls header +*/ + + +#ifndef HGEGUICTRLS_H +#define HGEGUICTRLS_H + + +#include "hge.h" +#include "hgesprite.h" +#include "hgefont.h" +#include "hgerect.h" +#include "hgegui.h" + + +#define hgeButtonGetState(gui,id) ((hgeGUIButton*)gui->GetCtrl(id))->GetState() +#define hgeButtonSetState(gui,id,b) ((hgeGUIButton*)gui->GetCtrl(id))->SetState(b) +#define hgeSliderGetValue(gui,id) ((hgeGUISlider*)gui->GetCtrl(id))->GetValue() +#define hgeSliderSetValue(gui,id,f) ((hgeGUISlider*)gui->GetCtrl(id))->SetValue(f) +#define hgeGetTextCtrl(gui,id) ((hgeGUIText*)gui->GetCtrl(id)) +#define hgeGetListboxCtrl(gui,id) ((hgeGUIListbox*)gui->GetCtrl(id)) + + +/* +** hgeGUIText +*/ +class hgeGUIText : public hgeGUIObject +{ +public: + hgeGUIText(int id, float x, float y, float w, float h, hgeFont *fnt); + + void SetMode(int _align); + void SetText(const char *_text); + void printf(const char *format, ...); + + virtual void Render(); + +private: + hgeFont* font; + float tx, ty; + int align; + char text[256]; +}; + + +/* +** hgeGUIButton +*/ +class hgeGUIButton : public hgeGUIObject +{ +public: + hgeGUIButton(int id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty); + virtual ~hgeGUIButton(); + + void SetMode(bool _bTrigger) { bTrigger=_bTrigger; } + void SetState(bool _bPressed) { bPressed=_bPressed; } + bool GetState() const { return bPressed; } + + virtual void Render(); + virtual bool MouseLButton(bool bDown); + +private: + bool bTrigger; + bool bPressed; + bool bOldState; + hgeSprite *sprUp, *sprDown; +}; + + +/* +** hgeGUISlider +*/ +#define HGESLIDER_BAR 0 +#define HGESLIDER_BARRELATIVE 1 +#define HGESLIDER_SLIDER 2 + +class hgeGUISlider : public hgeGUIObject +{ +public: + hgeGUISlider(int id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty, float sw, float sh, bool vertical=false); + virtual ~hgeGUISlider(); + + void SetMode(float _fMin, float _fMax, int _mode) { fMin=_fMin; fMax=_fMax; mode=_mode; } + void SetValue(float _fVal); + float GetValue() const { return fVal; } + + virtual void Render(); + virtual bool MouseMove(float x, float y); + virtual bool MouseLButton(bool bDown); + +private: + bool bPressed; + bool bVertical; + int mode; + float fMin, fMax, fVal; + float sl_w, sl_h; + hgeSprite *sprSlider; +}; + + +/* +** hgeGUIListbox +*/ +struct hgeGUIListboxItem +{ + char text[64]; + hgeGUIListboxItem *next; +}; + +class hgeGUIListbox : public hgeGUIObject +{ +public: + hgeGUIListbox(int id, float x, float y, float w, float h, hgeFont *fnt, DWORD tColor, DWORD thColor, DWORD hColor); + virtual ~hgeGUIListbox(); + + int AddItem(char *item); + void DeleteItem(int n); + int GetSelectedItem() { return nSelectedItem; } + void SetSelectedItem(int n) { if(n>=0 && n<GetNumItems()) nSelectedItem=n; } + int GetTopItem() { return nTopItem; } + void SetTopItem(int n) { if(n>=0 && n<=GetNumItems()-GetNumRows()) nTopItem=n; } + + char *GetItemText(int n); + int GetNumItems() { return nItems; } + int GetNumRows() { return int((rect.y2-rect.y1)/font->GetHeight()); } + void Clear(); + + virtual void Render(); + virtual bool MouseMove(float x, float y) { mx=x; my=y; return false; } + virtual bool MouseLButton(bool bDown); + virtual bool MouseWheel(int nNotches); + virtual bool KeyClick(int key, int chr); + +private: + hgeSprite *sprHighlight; + hgeFont *font; + DWORD textColor, texthilColor; + + int nItems, nSelectedItem, nTopItem; + float mx, my; + hgeGUIListboxItem *pItems; +}; + + +#endif diff --git a/archive/include/hgeparticle.h b/archive/include/hgeparticle.h new file mode 100644 index 0000000..fd1e622 --- /dev/null +++ b/archive/include/hgeparticle.h @@ -0,0 +1,168 @@ +// PLEASE NOTE that this is not the 1.81 version of hgeparticle.h ... +// the game I'm working on used an older HGE that breaks with the 1.81 +// particle system. If you want 1.81, add the "bRelative" stuff to it. --ryan. + +/* +** Haaf's Game Engine 1.61 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeParticleSystem helper class header +*/ + + +#ifndef HGEPARTICLE_H +#define HGEPARTICLE_H + + +#include "hge.h" +#include "hgesprite.h" +#include "hgevector.h" +#include "hgecolor.h" +#include "hgerect.h" + + +#define MAX_PARTICLES 500 +#define MAX_PSYSTEMS 100 + +struct hgeParticle +{ + hgeVector vecLocation; + hgeVector vecVelocity; + + float fGravity; + float fRadialAccel; + float fTangentialAccel; + + float fSpin; + float fSpinDelta; + + float fSize; + float fSizeDelta; + + hgeColor colColor; // + alpha + hgeColor colColorDelta; + + float fAge; + float fTerminalAge; +}; + +struct hgeParticleSystemInfo +{ + hgeSprite* sprite; // texture + blend mode + int nEmission; // particles per sec + float fLifetime; + + float fParticleLifeMin; + float fParticleLifeMax; + + float fDirection; + float fSpread; + BYTE bRelative; // was "bool", but that's 4 bytes on PowerPC instead of 1, and it broke loading from disk... + + float fSpeedMin; + float fSpeedMax; + + float fGravityMin; + float fGravityMax; + + float fRadialAccelMin; + float fRadialAccelMax; + + float fTangentialAccelMin; + float fTangentialAccelMax; + + float fSizeStart; + float fSizeEnd; + float fSizeVar; + + float fSpinStart; + float fSpinEnd; + float fSpinVar; + + hgeColor colColorStart; // + alpha + hgeColor colColorEnd; + float fColorVar; + float fAlphaVar; +}; + +class hgeParticleSystem +{ +public: + hgeParticleSystemInfo info; + + hgeParticleSystem(const char *filename, hgeSprite *sprite, float fps=0.0f); + hgeParticleSystem(hgeParticleSystemInfo *psi, float fps=0.0f); + hgeParticleSystem(const hgeParticleSystem &ps); + ~hgeParticleSystem() { hge->Release(); } + + hgeParticleSystem& operator= (const hgeParticleSystem &ps); + + + void Render(); + void FireAt(float x, float y); + void Fire(); + void Stop(bool bKillParticles=false); + void Update(float fDeltaTime); + void MoveTo(float x, float y, bool bMoveParticles=false); + void Transpose(float x, float y) { fTx=x; fTy=y; } + void TrackBoundingBox(bool bTrack) { bUpdateBoundingBox=bTrack; } + + int GetParticlesAlive() const { return nParticlesAlive; } + float GetAge() const { return fAge; } + void GetPosition(float *x, float *y) const { *x=vecLocation.x; *y=vecLocation.y; } + void GetTransposition(float *x, float *y) const { *x=fTx; *y=fTy; } + hgeRect* GetBoundingBox(hgeRect *rect) const { memcpy(rect, &rectBoundingBox, sizeof(hgeRect)); return rect; } + +private: + hgeParticleSystem(); + void _update(float fDeltaTime); + + static HGE *hge; + + float fUpdSpeed; + float fResidue; + + float fAge; + float fEmissionResidue; + + hgeVector vecPrevLocation; + hgeVector vecLocation; + float fTx, fTy; + + int nParticlesAlive; + hgeRect rectBoundingBox; + bool bUpdateBoundingBox; + + hgeParticle particles[MAX_PARTICLES]; +}; + +class hgeParticleManager +{ +public: + hgeParticleManager(float fps=0.0f); + ~hgeParticleManager(); + + void Update(float dt); + void Render(); + + hgeParticleSystem* SpawnPS(hgeParticleSystemInfo *psi, float x, float y); + bool IsPSAlive(hgeParticleSystem *ps) const; + void Transpose(float x, float y); + void GetTransposition(float *dx, float *dy) const {*dx=tX; *dy=tY;} + void KillPS(hgeParticleSystem *ps); + void KillAll(); + +private: + hgeParticleManager(const hgeParticleManager &); + hgeParticleManager& operator= (const hgeParticleManager &); + + float fFPS; + int nPS; + float tX; + float tY; + hgeParticleSystem* psList[MAX_PSYSTEMS]; +}; + + +#endif diff --git a/archive/include/hgerect.h b/archive/include/hgerect.h new file mode 100644 index 0000000..9e26907 --- /dev/null +++ b/archive/include/hgerect.h @@ -0,0 +1,35 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeRect helper class +*/ + + +#ifndef HGERECT_H +#define HGERECT_H + + +class hgeRect +{ +public: + float x1, y1, x2, y2; + + hgeRect(float _x1, float _y1, float _x2, float _y2) {x1=_x1; y1=_y1; x2=_x2; y2=_y2; bClean=false; } + hgeRect() {bClean=true;} + + void Clear() {bClean=true;} + bool IsClean() const {return bClean;} + void Set(float _x1, float _y1, float _x2, float _y2) { x1=_x1; x2=_x2; y1=_y1; y2=_y2; bClean=false; } + void SetRadius(float x, float y, float r) { x1=x-r; x2=x+r; y1=y-r; y2=y+r; bClean=false; } + void Encapsulate(float x, float y); + bool TestPoint(float x, float y) const; + bool Intersect(const hgeRect *rect) const; + +private: + bool bClean; +}; + + +#endif diff --git a/archive/include/hgeresource.h b/archive/include/hgeresource.h new file mode 100644 index 0000000..ace8f21 --- /dev/null +++ b/archive/include/hgeresource.h @@ -0,0 +1,85 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeResourceManager helper class header +*/ + + +#ifndef HGERESOURCE_H +#define HGERESOURCE_H + + +#include "hge.h" +#include "hgesprite.h" +#include "hgeanim.h" +#include "hgefont.h" +#include "hgeparticle.h" +#include "hgedistort.h" +#include "hgestrings.h" + + +#define RESTYPES 13 +#define MAXRESCHARS 128 + + +class hgeResourceManager; + +struct ResDesc +{ + char name[MAXRESCHARS]; + int resgroup; + size_t handle; + ResDesc* next; + + ResDesc() { hge=hgeCreate(HGE_VERSION); } + ~ResDesc() { hge->Release(); } + + virtual DWORD Get(hgeResourceManager *rm) = 0; + virtual void Free() = 0; + +protected: + static HGE *hge; +}; + +/* +** HGE Resource manager class +*/ +class hgeResourceManager +{ +public: + hgeResourceManager(const char *scriptname=0); + ~hgeResourceManager(); + + void ChangeScript(const char *scriptname=0); + bool Precache(int groupid=0); + void Purge(int groupid=0); + + void* GetResource(const char *name, int resgroup=0); + HTEXTURE GetTexture(const char *name, int resgroup=0); + HEFFECT GetEffect(const char *name, int resgroup=0); + HMUSIC GetMusic(const char *name, int resgroup=0); + HSTREAM GetStream(const char *name, int resgroup=0); + HTARGET GetTarget(const char *name); + + hgeSprite* GetSprite(const char *name); + hgeAnimation* GetAnimation(const char *name); + hgeFont* GetFont(const char *name); + hgeParticleSystem* GetParticleSystem(const char *name); + hgeDistortionMesh* GetDistortionMesh(const char *name); + hgeStringTable* GetStringTable(const char *name, int resgroup=0); + + ResDesc* res[RESTYPES]; + +private: + hgeResourceManager(const hgeResourceManager &); + hgeResourceManager& operator= (const hgeResourceManager&); + void _remove_all(); + void _parse_script(const char *scriptname=0); + + static HGE *hge; +}; + + +#endif diff --git a/archive/include/hgesprite.h b/archive/include/hgesprite.h new file mode 100644 index 0000000..e414c02 --- /dev/null +++ b/archive/include/hgesprite.h @@ -0,0 +1,67 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeSprite helper class header +*/ + + +#ifndef HGESPRITE_H +#define HGESPRITE_H + + +#include "hge.h" +#include "hgerect.h" + + +/* +** HGE Sprite class +*/ +class hgeSprite +{ +public: + hgeSprite(HTEXTURE tex, float x, float y, float w, float h); + hgeSprite(const hgeSprite &spr); + ~hgeSprite() { hge->Release(); } + + + void Render(float x, float y); + void RenderEx(float x, float y, float rot, float hscale=1.0f, float vscale=0.0f); + void RenderStretch(float x1, float y1, float x2, float y2); + void Render4V(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); + + void SetTexture(HTEXTURE tex); + void SetTextureRect(float x, float y, float w, float h, bool adjSize = true); + void SetColor(DWORD col, int i=-1); + void SetZ(float z, int i=-1); + void SetBlendMode(int blend) { quad.blend=blend; } + void SetHotSpot(float x, float y) { hotX=x; hotY=y; } + void SetFlip(bool bX, bool bY, bool bHotSpot = false); + + HTEXTURE GetTexture() const { return quad.tex; } + void GetTextureRect(float *x, float *y, float *w, float *h) const { *x=tx; *y=ty; *w=width; *h=height; } + DWORD GetColor(int i=0) const { return quad.v[i].col; } + float GetZ(int i=0) const { return quad.v[i].z; } + int GetBlendMode() const { return quad.blend; } + void GetHotSpot(float *x, float *y) const { *x=hotX; *y=hotY; } + void GetFlip(bool *bX, bool *bY) const { *bX=bXFlip; *bY=bYFlip; } + + float GetWidth() const { return width; } + float GetHeight() const { return height; } + hgeRect* GetBoundingBox(float x, float y, hgeRect *rect) const { rect->Set(x-hotX, y-hotY, x-hotX+width, y-hotY+height); return rect; } + hgeRect* GetBoundingBoxEx(float x, float y, float rot, float hscale, float vscale, hgeRect *rect) const; + +protected: + hgeSprite(); + static HGE *hge; + + hgeQuad quad; + float tx, ty, width, height; + float tex_width, tex_height; + float hotX, hotY; + bool bXFlip, bYFlip, bHSFlip; +}; + + +#endif diff --git a/archive/include/hgestrings.h b/archive/include/hgestrings.h new file mode 100644 index 0000000..e02cbe9 --- /dev/null +++ b/archive/include/hgestrings.h @@ -0,0 +1,48 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeStringTable helper class header +*/ + + +#ifndef HGESTRINGS_H +#define HGESTRINGS_H + + +#include "hge.h" + + +#define MAXSTRNAMELENGTH 64 + + +struct NamedString +{ + char name[MAXSTRNAMELENGTH]; + char *string; + NamedString *next; +}; + +/* +** HGE String table class +*/ +class hgeStringTable +{ +public: + hgeStringTable(const char *filename); + ~hgeStringTable(); + + char *GetString(const char *name); + +private: + hgeStringTable(const hgeStringTable &); + hgeStringTable& operator= (const hgeStringTable &); + + NamedString *strings; + + static HGE *hge; +}; + + +#endif diff --git a/archive/include/hgevector.h b/archive/include/hgevector.h new file mode 100644 index 0000000..b86bd01 --- /dev/null +++ b/archive/include/hgevector.h @@ -0,0 +1,54 @@ +/* +** Haaf's Game Engine 1.7 +** Copyright (C) 2003-2007, Relish Games +** hge.relishgames.com +** +** hgeVector helper class +*/ + + +#ifndef HGEVECTOR_H +#define HGEVECTOR_H + +#include <math.h> + +/* +** Fast 1.0/sqrtf(float) routine +*/ +float InvSqrt(float x); + +class hgeVector +{ +public: + float x,y; + + hgeVector(float _x, float _y) { x=_x; y=_y; } + hgeVector() { x=0; y=0; } + + hgeVector operator- () const { return hgeVector(-x, -y); } + hgeVector operator- (const hgeVector &v) const { return hgeVector(x-v.x, y-v.y); } + hgeVector operator+ (const hgeVector &v) const { return hgeVector(x+v.x, y+v.y); } + hgeVector& operator-= (const hgeVector &v) { x-=v.x; y-=v.y; return *this; } + hgeVector& operator+= (const hgeVector &v) { x+=v.x; y+=v.y; return *this; } + bool operator== (const hgeVector &v) const { return (x==v.x && y==v.y); } + bool operator!= (const hgeVector &v) const { return (x!=v.x || y!=v.y); } + + hgeVector operator/ (const float scalar) const { return hgeVector(x/scalar, y/scalar); } + hgeVector operator* (const float scalar) const { return hgeVector(x*scalar, y*scalar); } + hgeVector& operator*= (const float scalar) { x*=scalar; y*=scalar; return *this; } + + float Dot(const hgeVector *v) const { return x*v->x + y*v->y; } + float Length() const { return sqrtf(Dot(this)); } + float Angle(const hgeVector *v = 0) const; + + void Clamp(const float max) { if(Length() > max) { Normalize(); x *= max; y *= max; } } + hgeVector* Normalize() { float rc=InvSqrt(Dot(this)); x*=rc; y*=rc; return this; } + hgeVector* Rotate(float a); +}; + +inline hgeVector operator* (const float s, const hgeVector &v) { return v*s; } +inline float operator^ (const hgeVector &v, const hgeVector &u) { return v.Angle(&u); } +inline float operator% (const hgeVector &v, const hgeVector &u) { return v.Dot(&u); } + + +#endif diff --git a/archive/include/unix_compat.h b/archive/include/unix_compat.h new file mode 100644 index 0000000..56ec4b3 --- /dev/null +++ b/archive/include/unix_compat.h @@ -0,0 +1,165 @@ +#ifndef _INCL_UNIX_COMPAT_H_ +#define _INCL_UNIX_COMPAT_H_ + +#if (defined(__APPLE__) && defined(__MACH__)) +#define PLATFORM_MACOSX 1 +#endif + +#if ( defined(unix) || PLATFORM_MACOSX ) +#define PLATFORM_UNIX 1 +#endif + +// Useful to sprinkle around the codebase without a bunch of #ifdefs... +#ifdef _WINDOWS +#define BYTESWAP(x) +#define STUBBED(x) +#endif + +// don't want rest of this header on Windows, etc. +#if (PLATFORM_UNIX) + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <time.h> + +#include "/usr/include/SDL/SDL.h" + +#define _MAX_PATH PATH_MAX +#define MAX_PATH PATH_MAX + +typedef int64_t __int64; +typedef uint32_t DWORD; +typedef uint64_t UINT64; +typedef uint8_t BYTE; +typedef void *HANDLE; +typedef HANDLE HWND; +typedef int32_t BOOL; + +static inline DWORD timeGetTime(void) +{ + return SDL_GetTicks(); +} // timeGetTime + + +// macro so I know what is still on the TODO list... +#if 1 +#define STUBBED(x) +#else +void CalledSTUBBED(void); // you can set a breakpoint on this. +#define STUBBED(x) \ +do { \ + static bool seen_this = false; \ + if (!seen_this) { \ + seen_this = true; \ + fprintf(stderr, "STUBBED: %s at %s (%s:%d)\n", x, __FUNCTION__, __FILE__, __LINE__); \ + fflush(stderr); \ + CalledSTUBBED(); \ + } \ +} while (false) +#endif + +static inline char *itoa(const int i, char *s, const int radix) +{ + assert(radix == 10); + sprintf(s, "%d", i); + return s; +} + +static inline char *_i64toa(const __int64 i, char *s, const int radix) +{ + assert(radix == 10); + assert(sizeof (long long) == sizeof (__int64)); + sprintf(s, "%lld", (long long) i); + return s; +} + +static inline __int64 _atoi64(const char *str) +{ + return (__int64) strtoll(str, NULL, 10); +} + +static inline void Sleep(const int ms) +{ + usleep(ms * 1000); +} + +static inline char *_gcvt(const double value, const int digits, char *buffer) +{ + char fmt[32]; + snprintf(fmt, sizeof (fmt), "%%.%dg", digits); + sprintf(buffer, fmt, value); + return buffer; +} + +#define ZeroMemory(a,b) memset(a, '\0', b) + +#ifdef __cplusplus +#ifdef max +#undef max +#endif +template <class T> inline const T &max(const T &a, const T &b) { return (a > b) ? a : b; } +#ifdef min +#undef min +#endif +template <class T> inline const T &min(const T &a, const T &b) { return (a < b) ? a : b; } +#endif + +// Byteswap magic... + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +#define PLATFORM_BIGENDIAN 1 +#define PLATFORM_LITTLEENDIAN 0 +#else +#define PLATFORM_BIGENDIAN 0 +#define PLATFORM_LITTLEENDIAN 1 +#endif + +#if PLATFORM_BIGENDIAN + #define SWAPPER64(t) \ + inline void BYTESWAP(t &x) { \ + union { t orig; Uint64 ui; } swapper; \ + swapper.orig = x; \ + swapper.ui = SDL_SwapLE64(swapper.ui); \ + x = swapper.orig; \ + } + #define SWAPPER32(t) \ + inline void BYTESWAP(t &x) { \ + union { t orig; Uint32 ui; } swapper; \ + swapper.orig = x; \ + swapper.ui = SDL_SwapLE32(swapper.ui); \ + x = swapper.orig; \ + } + #define SWAPPER16(t) \ + inline void BYTESWAP(t &x) { \ + union { t orig; Uint16 ui; } swapper; \ + swapper.orig = x; \ + swapper.ui = SDL_SwapLE16(swapper.ui); \ + x = swapper.orig; \ + } + #define SWAPPER8(t) inline void BYTESWAP(t &_x) {} + SWAPPER64(double) + SWAPPER32(size_t) // !!! FIXME: this will fail on gnuc/amd64. + SWAPPER32(int) + SWAPPER32(float) + SWAPPER32(DWORD) + SWAPPER16(WORD) + SWAPPER16(short) + SWAPPER8(BYTE) + #undef SWAPPER32 + #undef SWAPPER16 + #undef SWAPPER8 +#else + #define BYTESWAP(x) +#endif + +#endif // PLATFORM_UNIX + +#endif // include-once blocker. |