redblade - here you are my version of system friendly screen without intuition ( only graphics primitves are used ). But I didn't find time to fight with input.device ( I spent some time yesterday but without resutls - but I create asm version of CreatePort and DeletePort ). And probably I will not back to input.device. I aggree with Wepl that is complicate to make 100% system conform - better is use C Language.
I used Asm-One / Asm-Pro. As you see there is a lot problems with creating system friendly screen without intuition ( especially if you want to support kick 1.3, kick 2.0, kick 3.0 ). Much easier in asm is make custom screen with invisible window ( to handle IDCMP events ) to achieve same result. all code is public domain. Of course this code comes with absolutely no warranty of any kind.
Code:
;
; system friendly screen ( without intuition )
;
; public domain
;=============================================================================
INCDIR includes:
INCLUDE exec/memory.i
INCLUDE dos/dos.i
INCLUDE graphics/gfxbase.i
INCLUDE graphics/videocontrol.i
INCLUDE graphics/rastport.i
INCLUDE lvo/exec.i
INCLUDE lvo/graphics.i
;===============
AbsExecBase = 4
SCREEN_DEPTH = 4
SCREEN_WIDTH = 320
SCREEN_HEIGHT = 256
SCREEN_COLORS = 16 ; 2^DEPTH
;=============================================================================
callexc MACRO
move.l (exec_base,a4),a6
jsr (_LVO\1,a6)
ENDM
callgfx MACRO
move.l (gfx_base,a4),a6
jsr (_LVO\1,a6)
ENDM
;=============================================================================
BASEREG DT,a4
SECTION scrcode,CODE_P
start:
;initialize
lea (DT),a4
bsr init_libs
bne .cleanup
;make screen
bsr do_screen
bne .cleanup
;main
bsr main
;clean up
.cleanup bsr cleanup
rts
;=============================================================================
main:
move.l #SIGBREAKF_CTRL_C,d0
callexc Wait
cmp.l #SIGBREAKF_CTRL_C,d0
bne main
rts
;=============================================================================
;;function init - initialize screen stuff
;
; in a4 - variable base
;
; out d0 - RETURN_OK if everything was fine, RETURN_FAIL otherwise
;
do_screen:
; - do mode id
; - do view
; - do bitmap
; - do viewport
; - do color map
; - do copper(s),
;set mode id ( form value from graphice/display.i )
move.l #DEFAULT_MONITOR_ID,(mode_id,a4)
;view stuff
bsr do_view
bne .exit
;bitmap stuff
bsr do_bitmap
bne .exit
;viewport stuff
bsr do_viewport
bne .exit
;color map
bsr do_colormap
bne .exit
;copper stuff
bsr do_copper
bne .exit
moveq #RETURN_OK,d0
.exit rts
;=============================================================================
do_copper:
;set colors
lea (view_port,a4),a0
lea (color_table,pc),a1
moveq #SCREEN_COLORS,d0
callgfx LoadRGB4
;construct preliminary Copper instruction list.
lea (view,a4),a0
lea (view_port,a4),a1
callgfx MakeVPort
;merge preliminary lists into a real Copper list in the View structure.
lea (view,a4),a1
callgfx MrgCop
lea (view,a4),a1
callgfx LoadView
;init rastport
lea (rast_port,a4),a1
callgfx InitRastPort
lea (rast_port,a4),a0
move.l (bitmap,a4),a1
move.l a1,(rp_BitMap,a0)
;clean all rast port with color 0 ( black )
lea (rast_port,a4),a1
moveq #0,d0
callgfx SetRast
moveq #RETURN_OK,d0
rts
;=============================================================================
close_copper:
;load old view
move.l (old_view,a4),a1
callgfx LoadView
callgfx WaitTOF
;free first copper list
lea (view,a4),a0
move.l (v_LOFCprList,a0),a0
callgfx FreeCprList
;!!!TODO what about LACE case ( need to free second copperlist too )
lea (view_port,a4),a0
callgfx FreeVPortCopLists
rts
;=============================================================================
do_colormap:
;Initialize the ColorMap
moveq #SCREEN_COLORS,d0
callgfx GetColorMap
move.l d0,(color_map,a4)
bne .attach_cm
moveq #RETURN_FAIL,d0
bra .exit
.attach_cm
;additional stuff for v36 and higher
cmp.w #36,(gfx_version,a4)
bcs .load_cm_13
;Get ready to attach the ColorMap, Release 2-style
lea (view_port,a4),a0
lea (tag_cm,pc),a1
move.l a0,(a1)
;Attach the color map and Release 2 extended structures
move.l (color_map,a4),a0
lea (vc_Tags,pc),a1
callgfx VideoControl
tst.l d0 ;0 mean ok
beq .exit_ok
;error 'Could not attach extended structures'
moveq #RETURN_FAIL,d0
bra .exit
.load_cm_13
;Attach the ColorMap, old 1.3-style
lea (view_port,a4),a0
move.l (color_map,a4),(vp_ColorMap,a0)
.exit_ok moveq #RETURN_OK,d0
.exit rts
;=============================================================================
close_colormap:
tst.l (color_map,a4)
beq .exit
move.l (color_map,a4),a0
callgfx FreeColorMap
.exit rts
;=============================================================================
do_viewport:
;initialize view port
lea (view_port,a4),a0
callgfx InitVPort
;link the ViewPort into the View
lea (view_port,a4),a0
lea (view,a4),a1
move.l a0,(v_ViewPort,a1)
lea (ras_info,a4),a1
move.l a1,(vp_RasInfo,a0)
move.w #SCREEN_WIDTH,(vp_DWidth,a0)
move.w #SCREEN_HEIGHT,(vp_DHeight,a0)
;!!!TODO
;in case you want hires or lace then
;set the display mode in the old-fashioned way (V_LACE, V_HIRES ) to vp_Modes
;--- additional stuff for v36 and higher
cmp.w #36,(gfx_version,a4)
bcs .exit_ok
;make a ViewPortExtra and get ready to attach it
moveq #VIEWPORT_EXTRA_TYPE,d0
callgfx GfxNew
move.l d0,(vp_extra,a4)
bne .tag_vpextra
;error 'could not get View Port Extra'
moveq #RETURN_FAIL,d0
bra .exit
.tag_vpextra lea (tag_vpextra,pc),a0
move.l (vp_extra,a4),(a0)
;initialize the DisplayClip field of the ViewPortExtra
sub.l a0,a0
lea (dim_query,a4),a1
moveq #dim_SIZEOF,d0
move.l #DTAG_DIMS,d1
move.l #DEFAULT_MONITOR_ID,d2
callgfx GetDisplayInfoData
tst.l d0
bne .display_clip
;error 'could not get DimensionInfo'
moveq #RETURN_FAIL,d0
bra cleanup
.display_clip
lea (dim_query,a4),a0
move.l (vp_extra,a4),a1
move.l (dim_Nominal,a0),(vpe_DisplayClip,a1)
;make a DisplayInfo and get ready to attach it
move.l (mode_id,a4),d0
callgfx FindDisplayInfo
lea (tag_normal_disp,pc),a0
move.l d0,(a0)
bne .backwards_comp
;error 'could not get Display Info'
moveq #RETURN_FAIL,d0
bra .exit
.backwards_comp:
;This is for backwards compatibility with, for example,
;a 1.3 screen saver utility that looks at the Modes field
; viewPort.Modes = (UWORD) (modeID & 0x0000ffff);
lea (view_port,a4),a0
move.l (mode_id,a4),d0
move.w d0,(vp_Modes,a0)
.exit_ok moveq #RETURN_OK,d0
.exit rts
;=============================================================================
close_viewport:
tst.l (vp_extra,a4)
beq .exit
move.l (vp_extra,a4),a0
callgfx GfxFree
.exit rts
;=============================================================================
;;function do_bitmap - bitmap stuff
; - allocate memory for bitmap
; - set ras info
;
; in a4
; out d0 - RETURN_OK if everything was fine, RETURN_FAIL otherwise
;
do_bitmap:
;--- additional stuff for v39 and higher
cmp.w #39,(gfx_version,a4)
bcs .old_way
move.l #SCREEN_WIDTH,d0
move.l #SCREEN_HEIGHT,d1
moveq #SCREEN_DEPTH,d2
moveq #BMF_CLEAR|BMF_DISPLAYABLE|BMF_INTERLEAVED,d3
sub.l a0,a0
callgfx AllocBitMap
move.l d0,(bitmap,a4)
bne .init_ras_info
;error 'cannot allocate bitmap'
moveq #RETURN_FAIL,d0
bra .exit
;--- before v39 way ( AllocRaster )
.old_way
;allocate memory for BitMap structure
moveq #bm_SIZEOF,d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
callexc AllocMem
move.l d0,(bitmap,a4)
bne .init
;error 'cannot allocate bitmap structure'
moveq #RETURN_FAIL,d0
bra .exit
.init
;initialize BitMap structure
move.l (bitmap,a4),a0
moveq #SCREEN_DEPTH,d0
move.w #SCREEN_WIDTH,d1
move.w #SCREEN_HEIGHT,d2
callgfx InitBitMap
;allocate space for bitmap
move.l (bitmap,a4),a2
addq.l #bm_Planes,a2
moveq #SCREEN_DEPTH-1,d2
.alloc move.w #SCREEN_WIDTH,d0
move.w #SCREEN_HEIGHT,d1
callgfx AllocRaster
move.l d0,(a2)+
bne .next
;error 'could not allocate memory for bitmap'
moveq #RETURN_FAIL,d0
bra .exit
.next dbf d2,.alloc
.init_ras_info
;initialize ras info
lea (ras_info,a4),a0
move.l (bitmap,a4),(ri_BitMap,a0)
moveq #0,d0
move.w d0,(ri_RxOffset,a0)
move.w d0,(ri_RyOffset,a0)
move.l d0,(ri_Next,a0)
moveq #RETURN_OK,d0
.exit rts
;=============================================================================
close_bitmap:
;different way for v39 and higher
cmp.w #39,(gfx_version,a4)
bcs .old_way
move.l (bitmap,a4),a0
callgfx FreeBitMap
bra .exit
.old_way
;free space for bitmap created with AllocRaster
move.l (bitmap,a4),a2
add.l #bm_Planes,a2
moveq #SCREEN_DEPTH-1,d2
.loop move.l (a2)+,d0
beq .next
move.l d0,a0
move.w #SCREEN_WIDTH,d0
move.w #SCREEN_HEIGHT,d1
callgfx FreeRaster
.next dbf d2,.loop
;free BitMap structure memory
tst.l (bitmap,a4)
beq .exit
move.l (bitmap,a4),a1
moveq #bm_SIZEOF,d0
callexc FreeMem
.exit rts
;=============================================================================
;;function do_vew - do all view stuff
;
; in a4
; out d0 - RETURN_OK if everything was ok, otherwise RETURN_FAIL
;
do_view:
;save current view ( example steal intuition screen )
move.l (gfx_base,a4),a0
move.l (gb_ActiView,a0),(old_view,a4)
;init view
lea (view,a4),a1
callgfx InitView
;--- additional stuff for v36 or higher ---
cmp.w #36,(gfx_version,a4)
bcs .exit_ok
;make room for view extra
moveq #VIEW_EXTRA_TYPE,d0
callgfx GfxNew
move.l d0,(view_extra,a4)
bne .attach_to_view
;error 'could not get ViewExtra'
moveq #RETURN_FAIL,d0
bra .exit
.attach_to_view
;attach the ViewExtra to the View
lea (view,a4),a0
move.l (view_extra,a4),a1
callgfx GfxAssociate
lea (view,a4),a0
or.w #EXTEND_VSTRUCT,(v_Modes,a0)
;create a MonitorSpec to the ViewExtra
sub.l a1,a1
move.l (mode_id,a4),d0
callgfx OpenMonitor
move.l d0,(mon_spec,a4)
bne .attach_to_vextra
;error 'could not get MonitorSpec'
moveq #RETURN_FAIL,d0
bra .exit
.attach_to_vextra
;attach MonitorSpec structure to the ViewExtra
move.l (view_extra,a4),a0
move.l (mon_spec,a4),(ve_Monitor,a0)
.exit_ok moveq #RETURN_OK,d0
.exit rts
;=============================================================================
close_view:
tst.l (mon_spec,a4)
beq .free_vextra
; free MonitorSpec created with OpenMonitor
move.l (mon_spec,a4),a0
callgfx CloseMonitor
.free_vextra tst.l (view_extra,a4)
beq .exit
;free view extra created with GfxNew
move.l (view_extra,a4),a0
callgfx GfxFree
.exit rts
;=============================================================================
cleanup:
bsr close_copper
bsr close_viewport
bsr close_bitmap
bsr close_view
bsr close_libs
.exit rts
;=============================================================================
;;function init_libs
;
; in a4
;
; out d0 - if success return RETURN_OK otherwise RETURN_FAIL
;
GFX_MIN_VERSION = 33 ;minimal supported version of graphics library
init_libs:
;store exec base
move.l (AbsExecBase).w,a6
move.l a6,(exec_base,a4)
;open graphics library
moveq #GFX_MIN_VERSION,d0
lea (gfx_name,pc),a1
callexc OpenLibrary
move.l d0,(gfx_base,a4)
bne .save_gfx_ver
moveq #RETURN_FAIL,d0
bra .exit
.save_gfx_ver
;save version of graphics library for later usage
move.l (gfx_base,a4),a0
move.w (LIB_VERSION,a0),(gfx_version,a4)
moveq #RETURN_OK,d0
.exit rts
;=============================================================================
;function close_libs
;
; in a4
;
; do -
;
close_libs:
tst.l (gfx_base,a4)
beq .exit
;close graphics library
move.l (gfx_base,a4),a1
callexc CloseLibrary
.exit rts
;=============================================================================
;=============================================================================
;in a2 - name
; d2 - pri
;out a0 - pointer to MsgPort
;
CreatePort:
;allocate signal
moveq #-1,d0
callexc AllocSignal
move.b d0,d3
cmp.b #-1,d0
beq .error_exit
;allocate MsgPort
moveq #MP_SIZE,d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
callexc AllocMem
tst.l d0
bne .fill_in
moveq #0,d0
move.b d2,d0
callexc FreeSignal
bra .error_exit
.fill_in move.l d0,a0
move.l a2,(LN_NAME,a0)
move.b d2,(LN_PRI,a0)
move.b #NT_MSGPORT,(LN_TYPE,a0)
move.b #PA_SIGNAL,(MP_FLAGS,a0)
move.b d3,(MP_SIGBIT,a0)
move.l a0,-(sp)
sub.l a1,a1
callexc FindTask
move.l (sp)+,a0
move.l d0,(MP_SIGTASK,a0)
move.l a2,d0
tst.l d0
bne .add_port
move.l a0,-(sp)
add.l #MP_MSGLIST,a0
NEWLIST a0
move.l (sp)+,a0
rts
.add_port
move.l a0,-(sp)
move.l a0,a1
callexc AddPort
move.l (sp)+,a0
rts
.error_exit: sub.l a0,a0
rts
sig_bit: dc.b 0
EVEN
;=============================================================================
; in a0 - pointer MsgPort created with CreatePort
;
DeletePort:
move.l a0,a2
move.l (LN_NAME,a0),d0
tst.l d0
beq .clear
move.l a2,a1
callexc RemPort
move.l a2,a0
.clear moveq #-1,d0
move.l d0,(MP_SIGTASK,a0)
move.l d0,(MP_MSGLIST+LH_HEAD)
moveq #0,d0
move.b (MP_SIGBIT,a0),d0
callexc FreeSignal
move.l a2,a1
moveq #MP_SIZE,d0
callexc FreeMem
rts
;=============================================================================
;
; data
;
gfx_name: dc.b "graphics.library",0
CNOP 0,4
vc_Tags: dc.l VTAG_ATTACH_CM_SET
tag_cm dc.l 0
dc.l VTAG_VIEWPORTEXTRA_SET
tag_vpextra dc.l 0
dc.l VTAG_NORMAL_DISP_SET
tag_normal_disp dc.l 0
dc.l VTAG_END_CM,0
color_table
dc.w 0
dc.w $0fff
dc.w $0f0f
dc.w $0f00
dc.w 0,0,0,0,0,0,0,0
dc.w 0,0,0,0,0,0,0,0
;=============================================================================
SECTION scrbss,BSS_P
DT EQU *
exec_base: ds.l 1
gfx_base: ds.l 1
gfx_version: ds.w 1
old_view: ds.l 1
mode_id: ds.l 1 ;form value from graphics/display.i
;pointer to view extra structure ( graphics/view.i )
view_extra: ds.l 1
;pointer to MonitorSpec structure ( graphics/monitor.i )
mon_spec: ds.l 1
;View structure ( graphics/view.i )
view: ds.b v_SIZEOF
;pointer to BitMap structure ( graphics/gfx.i )
bitmap: ds.l 1
;RasInfo structure ( graphics/view.i )
ras_info: ds.b ri_SIZEOF
;ViewPort structure ( graphics/view.i )
view_port: ds.b vp_SIZEOF
;pointer to ViewPortExtra structure ( grpahics/view.i )
vp_extra ds.l 1
;structure DimensionInfo (graphics/displayinfo.i )
dim_query: ds.b dim_SIZEOF
;pointer to ColorMap structure ( gfraphics/view.i )
color_map: ds.l 1
;RastPort structure ( graphics/rastport.i )
rast_port: ds.b rp_SIZEOF
|